Upgrade our copy of llvm/clang to r135360, from upstream's trunk.

This commit is contained in:
Dimitry Andric 2011-07-17 19:51:40 +00:00
commit 17a519f92f
1144 changed files with 62943 additions and 37158 deletions

View File

@ -68,13 +68,6 @@ typedef struct LLVMOpaqueModule *LLVMModuleRef;
*/ */
typedef struct LLVMOpaqueType *LLVMTypeRef; typedef struct LLVMOpaqueType *LLVMTypeRef;
/**
* When building recursive types using LLVMRefineType, LLVMTypeRef values may
* become invalid; use LLVMTypeHandleRef to resolve this problem. See the
* llvm::AbstractTypeHolder class.
*/
typedef struct LLVMOpaqueTypeHandle *LLVMTypeHandleRef;
typedef struct LLVMOpaqueValue *LLVMValueRef; typedef struct LLVMOpaqueValue *LLVMValueRef;
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef; typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
@ -206,7 +199,6 @@ typedef enum {
LLVMStructTypeKind, /**< Structures */ LLVMStructTypeKind, /**< Structures */
LLVMArrayTypeKind, /**< Arrays */ LLVMArrayTypeKind, /**< Arrays */
LLVMPointerTypeKind, /**< Pointers */ LLVMPointerTypeKind, /**< Pointers */
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
LLVMMetadataTypeKind, /**< Metadata */ LLVMMetadataTypeKind, /**< Metadata */
LLVMX86_MMXTypeKind /**< X86 MMX */ LLVMX86_MMXTypeKind /**< X86 MMX */
@ -320,12 +312,6 @@ void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple);
const char *LLVMGetTarget(LLVMModuleRef M); const char *LLVMGetTarget(LLVMModuleRef M);
void LLVMSetTarget(LLVMModuleRef M, const char *Triple); void LLVMSetTarget(LLVMModuleRef M, const char *Triple);
/** See Module::addTypeName. */
LLVMBool LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty);
void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name);
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
const char *LLVMGetTypeName(LLVMModuleRef M, LLVMTypeRef Ty);
/** See Module::dump. */ /** See Module::dump. */
void LLVMDumpModule(LLVMModuleRef M); void LLVMDumpModule(LLVMModuleRef M);
@ -401,9 +387,16 @@ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
unsigned ElementCount, LLVMBool Packed); unsigned ElementCount, LLVMBool Packed);
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
LLVMBool Packed); LLVMBool Packed);
LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
unsigned ElementCount, LLVMBool Packed);
unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy);
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
/* Operations on array, pointer, and vector types (sequence types) */ /* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
@ -418,21 +411,12 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
/* Operations on other types */ /* Operations on other types */
LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMOpaqueTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMVoidType(void); LLVMTypeRef LLVMVoidType(void);
LLVMTypeRef LLVMLabelType(void); LLVMTypeRef LLVMLabelType(void);
LLVMTypeRef LLVMOpaqueType(void);
LLVMTypeRef LLVMX86MMXType(void); LLVMTypeRef LLVMX86MMXType(void);
/* Operations on type handles */
LLVMTypeHandleRef LLVMCreateTypeHandle(LLVMTypeRef PotentiallyAbstractTy);
void LLVMRefineType(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy);
LLVMTypeRef LLVMResolveTypeHandle(LLVMTypeHandleRef TypeHandle);
void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle);
/*===-- Values ------------------------------------------------------------===*/ /*===-- Values ------------------------------------------------------------===*/
/* The bulk of LLVM's object model consists of values, which comprise a very /* The bulk of LLVM's object model consists of values, which comprise a very
@ -581,6 +565,9 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef *ConstantVals, unsigned Length); LLVMValueRef *ConstantVals, unsigned Length);
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
LLVMBool Packed); LLVMBool Packed);
LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy,
LLVMValueRef *ConstantVals,
unsigned Count);
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size); LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
/* Constant expressions */ /* Constant expressions */
@ -1117,7 +1104,6 @@ namespace llvm {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )

View File

@ -41,6 +41,11 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef;
#include "llvm/Config/Targets.def" #include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */ #undef LLVM_TARGET /* Explicit undef to make SWIG happier */
#define LLVM_TARGET(TargetName) \
void LLVMInitialize##TargetName##MCAsmInfo(void);
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
/** LLVMInitializeAllTargetInfos - The main program should call this function if /** LLVMInitializeAllTargetInfos - The main program should call this function if
it wants access to all available targets that LLVM is configured to it wants access to all available targets that LLVM is configured to
support. */ support. */
@ -67,6 +72,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
#ifdef LLVM_NATIVE_TARGET #ifdef LLVM_NATIVE_TARGET
LLVM_NATIVE_TARGETINFO(); LLVM_NATIVE_TARGETINFO();
LLVM_NATIVE_TARGET(); LLVM_NATIVE_TARGET();
LLVM_NATIVE_MCASMINFO();
return 0; return 0;
#else #else
return 1; return 1;
@ -141,12 +147,6 @@ unsigned LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy, unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned Element); unsigned Element);
/** Struct layouts are speculatively cached. If a TargetDataRef is alive when
types are being refined and removed, this method must be called whenever a
struct type is removed to avoid a dangling pointer in this cache.
See the method llvm::TargetData::InvalidateStructLayoutInfo. */
void LLVMInvalidateStructLayout(LLVMTargetDataRef, LLVMTypeRef StructTy);
/** Deallocates a TargetData. /** Deallocates a TargetData.
See the destructor llvm::TargetData::~TargetData. */ See the destructor llvm::TargetData::~TargetData. */
void LLVMDisposeTargetData(LLVMTargetDataRef); void LLVMDisposeTargetData(LLVMTargetDataRef);

View File

@ -30,9 +30,6 @@ void LLVMAddConstantMergePass(LLVMPassManagerRef PM);
/** See llvm::createDeadArgEliminationPass function. */ /** See llvm::createDeadArgEliminationPass function. */
void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM); void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM);
/** See llvm::createDeadTypeEliminationPass function. */
void LLVMAddDeadTypeEliminationPass(LLVMPassManagerRef PM);
/** See llvm::createFunctionAttrsPass function. */ /** See llvm::createFunctionAttrsPass function. */
void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM); void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);

View File

@ -109,6 +109,7 @@ namespace llvm {
typedef signed short exponent_t; typedef signed short exponent_t;
struct fltSemantics; struct fltSemantics;
class APSInt;
class StringRef; class StringRef;
/* When bits of a floating point number are truncated, this enum is /* When bits of a floating point number are truncated, this enum is
@ -283,6 +284,7 @@ namespace llvm {
opStatus convert(const fltSemantics &, roundingMode, bool *); opStatus convert(const fltSemantics &, roundingMode, bool *);
opStatus convertToInteger(integerPart *, unsigned int, bool, opStatus convertToInteger(integerPart *, unsigned int, bool,
roundingMode, bool *) const; roundingMode, bool *) const;
opStatus convertToInteger(APSInt&, roundingMode, bool *) const;
opStatus convertFromAPInt(const APInt &, opStatus convertFromAPInt(const APInt &,
bool, roundingMode); bool, roundingMode);
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int, opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,

View File

@ -1241,18 +1241,19 @@ public:
/// toString - Converts an APInt to a string and append it to Str. Str is /// toString - Converts an APInt to a string and append it to Str. Str is
/// commonly a SmallString. /// commonly a SmallString.
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const; void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the /// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16. /// radix given. The radix can be 2, 8, 10 or 16.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, false); toString(Str, Radix, false, false);
} }
/// Considers the APInt to be signed and converts it into a string in the /// Considers the APInt to be signed and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16. /// radix given. The radix can be 2, 8, 10 or 16.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, true); toString(Str, Radix, true, false);
} }
/// toString - This returns the APInt as a std::string. Note that this is an /// toString - This returns the APInt as a std::string. Note that this is an

View File

@ -39,7 +39,7 @@ namespace llvm {
const T *Data; const T *Data;
/// The number of elements. /// The number of elements.
size_t Length; size_type Length;
public: public:
/// @name Constructors /// @name Constructors
@ -56,6 +56,10 @@ namespace llvm {
/*implicit*/ ArrayRef(const T *data, size_t length) /*implicit*/ ArrayRef(const T *data, size_t length)
: Data(data), Length(length) {} : Data(data), Length(length) {}
/// Construct an ArrayRef from a range.
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector. /// Construct an ArrayRef from a SmallVector.
/*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec) /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {} : Data(Vec.data()), Length(Vec.size()) {}
@ -96,6 +100,16 @@ namespace llvm {
return Data[Length-1]; return Data[Length-1];
} }
/// equals - Check for element-wise equality.
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
return false;
for (size_type i = 0; i != Length; i++)
if (Data[i] != RHS.Data[i])
return false;
return true;
}
/// slice(n) - Chop off the first N elements of the array. /// slice(n) - Chop off the first N elements of the array.
ArrayRef<T> slice(unsigned N) { ArrayRef<T> slice(unsigned N) {
assert(N <= size() && "Invalid specifier"); assert(N <= size() && "Invalid specifier");
@ -124,9 +138,31 @@ namespace llvm {
return std::vector<T>(Data, Data+Length); return std::vector<T>(Data, Data+Length);
} }
/// @}
/// @name Conversion operators
/// @{
operator std::vector<T>() const {
return std::vector<T>(Data, Data+Length);
}
/// @} /// @}
}; };
/// @name ArrayRef Comparison Operators
/// @{
template<typename T>
inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return LHS.equals(RHS);
}
template<typename T>
inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return !(LHS == RHS);
}
/// @}
// ArrayRefs can be treated like a POD type. // ArrayRefs can be treated like a POD type.
template <typename T> struct isPodLike; template <typename T> struct isPodLike;
template <typename T> struct isPodLike<ArrayRef<T> > { template <typename T> struct isPodLike<ArrayRef<T> > {

View File

@ -103,6 +103,14 @@ public:
/// isEmpty - Returns true if the list is empty. /// isEmpty - Returns true if the list is empty.
bool isEmpty() const { return !X; } bool isEmpty() const { return !X; }
bool contains(const T& V) const {
for (iterator I = begin(), E = end(); I != E; ++I) {
if (*I == V)
return true;
}
return false;
}
/// isEqual - Returns true if two lists are equal. Because all lists created /// isEqual - Returns true if two lists are equal. Because all lists created
/// from the same ImmutableListFactory are uniqued, this has O(1) complexity /// from the same ImmutableListFactory are uniqued, this has O(1) complexity
/// because it the contents of the list do not need to be compared. Note /// because it the contents of the list do not need to be compared. Note

View File

@ -90,7 +90,7 @@ public:
Vec.setValue(Vec.Bits, Idx, val); Vec.setValue(Vec.Bits, Idx, val);
return *this; return *this;
} }
operator T() { operator T() const {
return Vec.getValue(Vec.Bits, Idx); return Vec.getValue(Vec.Bits, Idx);
} }
}; };

View File

@ -410,7 +410,14 @@ public:
this->setEnd(this->end()+1); this->setEnd(this->end()+1);
// Push everything else over. // Push everything else over.
std::copy_backward(I, this->end()-1, this->end()); std::copy_backward(I, this->end()-1, this->end());
*I = Elt;
// If we just moved the element we're inserting, be sure to update
// the reference.
const T *EltPtr = &Elt;
if (I <= EltPtr && EltPtr < this->EndX)
++EltPtr;
*I = *EltPtr;
return I; return I;
} }
size_t EltNo = I-this->begin(); size_t EltNo = I-this->begin();

View File

@ -140,7 +140,7 @@ public:
/// StringMapEntry object. /// StringMapEntry object.
const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);} const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
const char *first() const { return getKeyData(); } StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
/// Create - Create a StringMapEntry for the specified key and default /// Create - Create a StringMapEntry for the specified key and default
/// construct the value. /// construct the value.
@ -307,7 +307,7 @@ public:
return ValueTy(); return ValueTy();
} }
ValueTy& operator[](StringRef Key) { ValueTy &operator[](StringRef Key) {
return GetOrCreateValue(Key).getValue(); return GetOrCreateValue(Key).getValue();
} }
@ -355,8 +355,7 @@ public:
/// exists, return it. Otherwise, default construct a value, insert it, and /// exists, return it. Otherwise, default construct a value, insert it, and
/// return. /// return.
template <typename InitTy> template <typename InitTy>
StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key, MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
InitTy Val) {
unsigned BucketNo = LookupBucketFor(Key); unsigned BucketNo = LookupBucketFor(Key);
ItemBucket &Bucket = TheTable[BucketNo]; ItemBucket &Bucket = TheTable[BucketNo];
if (Bucket.Item && Bucket.Item != getTombstoneVal()) if (Bucket.Item && Bucket.Item != getTombstoneVal())
@ -378,22 +377,10 @@ public:
return *NewItem; return *NewItem;
} }
StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key) { MapEntryTy &GetOrCreateValue(StringRef Key) {
return GetOrCreateValue(Key, ValueTy()); return GetOrCreateValue(Key, ValueTy());
} }
template <typename InitTy>
StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
const char *KeyEnd,
InitTy Val) {
return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart), Val);
}
StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
const char *KeyEnd) {
return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart));
}
/// remove - Remove the specified key/value pair from the map, but do not /// remove - Remove the specified key/value pair from the map, but do not
/// erase it. This aborts if the key is not in the map. /// erase it. This aborts if the key is not in the map.
void remove(MapEntryTy *KeyValue) { void remove(MapEntryTy *KeyValue) {

View File

@ -95,7 +95,8 @@ public:
Solaris, Solaris,
Win32, Win32,
Haiku, Haiku,
Minix Minix,
RTEMS
}; };
enum EnvironmentType { enum EnvironmentType {
UnknownEnvironment, UnknownEnvironment,
@ -237,19 +238,10 @@ public:
/// specialized because it is a common query. /// specialized because it is a common query.
unsigned getOSMajorVersion() const { unsigned getOSMajorVersion() const {
unsigned Maj, Min, Micro; unsigned Maj, Min, Micro;
getDarwinNumber(Maj, Min, Micro); getOSVersion(Maj, Min, Micro);
return Maj; return Maj;
} }
void getDarwinNumber(unsigned &Major, unsigned &Minor,
unsigned &Micro) const {
return getOSVersion(Major, Minor, Micro);
}
unsigned getDarwinMajorNumber() const {
return getOSMajorVersion();
}
/// isOSVersionLT - Helper function for doing comparisons against version /// isOSVersionLT - Helper function for doing comparisons against version
/// numbers included in the target triple. /// numbers included in the target triple.
bool isOSVersionLT(unsigned Major, unsigned Minor = 0, bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
@ -275,7 +267,7 @@ public:
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const { bool isOSDarwin() const {
return isMacOSX() ||getOS() == Triple::IOS; return isMacOSX() || getOS() == Triple::IOS;
} }
/// isOSWindows - Is this a "Windows" OS. /// isOSWindows - Is this a "Windows" OS.
@ -288,7 +280,7 @@ public:
/// compatibility, which handles supporting skewed version numbering schemes /// compatibility, which handles supporting skewed version numbering schemes
/// used by the "darwin" triples. /// used by the "darwin" triples.
unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0, unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
unsigned Micro = 0) const { unsigned Micro = 0) const {
assert(isMacOSX() && "Not an OS X triple!"); assert(isMacOSX() && "Not an OS X triple!");
// If this is OS X, expect a sane version number. // If this is OS X, expect a sane version number.
@ -299,7 +291,7 @@ public:
assert(Major == 10 && "Unexpected major version"); assert(Major == 10 && "Unexpected major version");
return isOSVersionLT(Minor + 4, Micro, 0); return isOSVersionLT(Minor + 4, Micro, 0);
} }
/// @} /// @}
/// @name Mutators /// @name Mutators
/// @{ /// @{

View File

@ -1,205 +0,0 @@
//===-- llvm/AbstractTypeUser.h - AbstractTypeUser Interface ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the AbstractTypeUser class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ABSTRACT_TYPE_USER_H
#define LLVM_ABSTRACT_TYPE_USER_H
#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H)
#error Do not include this file directly. Include Type.h instead.
#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method
#error PATypeHolder::dropRef() correctly otherwise.
#endif
// This is the "master" include for <cassert> Whether this file needs it or not,
// it must always include <cassert> for the files which include
// llvm/AbstractTypeUser.h
//
// In this way, most every LLVM source file will have access to the assert()
// macro without having to #include <cassert> directly.
//
#include <cassert>
namespace llvm {
class Value;
class Type;
class DerivedType;
template<typename T> struct simplify_type;
/// The AbstractTypeUser class is an interface to be implemented by classes who
/// could possibly use an abstract type. Abstract types are denoted by the
/// isAbstract flag set to true in the Type class. These are classes that
/// contain an Opaque type in their structure somewhere.
///
/// Classes must implement this interface so that they may be notified when an
/// abstract type is resolved. Abstract types may be resolved into more
/// concrete types through: linking, parsing, and bitcode reading. When this
/// happens, all of the users of the type must be updated to reference the new,
/// more concrete type. They are notified through the AbstractTypeUser
/// interface.
///
/// In addition to this, AbstractTypeUsers must keep the use list of the
/// potentially abstract type that they reference up-to-date. To do this in a
/// nice, transparent way, the PATypeHandle class is used to hold "Potentially
/// Abstract Types", and keep the use list of the abstract types up-to-date.
/// @brief LLVM Abstract Type User Representation
class AbstractTypeUser {
protected:
virtual ~AbstractTypeUser(); // Derive from me
/// setType - It's normally not possible to change a Value's type in place,
/// but an AbstractTypeUser subclass that knows what its doing can be
/// permitted to do so with care.
void setType(Value *V, const Type *NewTy);
public:
/// refineAbstractType - The callback method invoked when an abstract type is
/// resolved to another type. An object must override this method to update
/// its internal state to reference NewType instead of OldType.
///
virtual void refineAbstractType(const DerivedType *OldTy,
const Type *NewTy) = 0;
/// The other case which AbstractTypeUsers must be aware of is when a type
/// makes the transition from being abstract (where it has clients on its
/// AbstractTypeUsers list) to concrete (where it does not). This method
/// notifies ATU's when this occurs for a type.
///
virtual void typeBecameConcrete(const DerivedType *AbsTy) = 0;
// for debugging...
virtual void dump() const = 0;
};
/// PATypeHandle - Handle to a Type subclass. This class is used to keep the
/// use list of abstract types up-to-date.
///
class PATypeHandle {
const Type *Ty;
AbstractTypeUser * const User;
// These functions are defined at the bottom of Type.h. See the comment there
// for justification.
void addUser();
void removeUser();
public:
// ctor - Add use to type if abstract. Note that Ty must not be null
inline PATypeHandle(const Type *ty, AbstractTypeUser *user)
: Ty(ty), User(user) {
addUser();
}
// ctor - Add use to type if abstract.
inline PATypeHandle(const PATypeHandle &T) : Ty(T.Ty), User(T.User) {
addUser();
}
// dtor - Remove reference to type...
inline ~PATypeHandle() { removeUser(); }
// Automatic casting operator so that the handle may be used naturally
inline operator Type *() const { return const_cast<Type*>(Ty); }
inline Type *get() const { return const_cast<Type*>(Ty); }
// operator= - Allow assignment to handle
inline Type *operator=(const Type *ty) {
if (Ty != ty) { // Ensure we don't accidentally drop last ref to Ty
removeUser();
Ty = ty;
addUser();
}
return get();
}
// operator= - Allow assignment to handle
inline const Type *operator=(const PATypeHandle &T) {
return operator=(T.Ty);
}
inline bool operator==(const Type *ty) {
return Ty == ty;
}
// operator-> - Allow user to dereference handle naturally...
inline const Type *operator->() const { return Ty; }
};
/// PATypeHolder - Holder class for a potentially abstract type. This uses
/// efficient union-find techniques to handle dynamic type resolution. Unless
/// you need to do custom processing when types are resolved, you should always
/// use PATypeHolders in preference to PATypeHandles.
///
class PATypeHolder {
mutable const Type *Ty;
void destroy();
public:
PATypeHolder() : Ty(0) {}
PATypeHolder(const Type *ty) : Ty(ty) {
addRef();
}
PATypeHolder(const PATypeHolder &T) : Ty(T.Ty) {
addRef();
}
~PATypeHolder() { dropRef(); }
operator Type *() const { return get(); }
Type *get() const;
// operator-> - Allow user to dereference handle naturally...
Type *operator->() const { return get(); }
// operator= - Allow assignment to handle
Type *operator=(const Type *ty) {
if (Ty != ty) { // Don't accidentally drop last ref to Ty.
dropRef();
Ty = ty;
addRef();
}
return get();
}
Type *operator=(const PATypeHolder &H) {
return operator=(H.Ty);
}
/// getRawType - This should only be used to implement the vmcore library.
///
const Type *getRawType() const { return Ty; }
private:
void addRef();
void dropRef();
friend class TypeMapBase;
};
// simplify_type - Allow clients to treat uses just like values when using
// casting operators.
template<> struct simplify_type<PATypeHolder> {
typedef const Type* SimpleType;
static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
return static_cast<SimpleType>(Val.get());
}
};
template<> struct simplify_type<const PATypeHolder> {
typedef const Type* SimpleType;
static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
return static_cast<SimpleType>(Val.get());
}
};
} // End llvm namespace
#endif

View File

@ -0,0 +1,53 @@
//========-------- BlockFrequency.h - Block Frequency Analysis -------========//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loops should be simplified before this analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H
#define LLVM_ANALYSIS_BLOCKFREQUENCY_H
#include "llvm/Pass.h"
#include <climits>
namespace llvm {
class BranchProbabilityInfo;
template<class BlockT, class FunctionT, class BranchProbInfoT>
class BlockFrequencyImpl;
/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate
/// IR basic block frequencies.
class BlockFrequency : public FunctionPass {
BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
public:
static char ID;
BlockFrequency();
~BlockFrequency();
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
/// getblockFreq - Return block frequency. Never return 0, value must be
/// positive. Please note that initial frequency is equal to 1024. It means
/// that we should not rely on the value itself, but only on the comparison to
/// the other block frequencies. We do this to avoid using of the floating
/// points.
uint32_t getBlockFreq(BasicBlock *BB);
};
}
#endif

View File

@ -0,0 +1,349 @@
//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Shared implementation of BlockFrequency for IR and Machine Instructions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#include "llvm/BasicBlock.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <vector>
#include <sstream>
#include <string>
namespace llvm {
class BlockFrequency;
class MachineBlockFrequency;
/// BlockFrequencyImpl implements block frequency algorithm for IR and
/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
/// for the entry block and then propagates frequencies using branch weights
/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
/// algorithm can find "backedges" by itself.
template<class BlockT, class FunctionT, class BlockProbInfoT>
class BlockFrequencyImpl {
DenseMap<BlockT *, uint32_t> Freqs;
BlockProbInfoT *BPI;
FunctionT *Fn;
typedef GraphTraits< Inverse<BlockT *> > GT;
static const uint32_t START_FREQ = 1024;
std::string getBlockName(BasicBlock *BB) const {
return BB->getNameStr();
}
std::string getBlockName(MachineBasicBlock *MBB) const {
std::stringstream ss;
ss << "BB#" << MBB->getNumber();
if (const BasicBlock *BB = MBB->getBasicBlock())
ss << " derived from LLVM BB " << BB->getNameStr();
return ss.str();
}
void setBlockFreq(BlockT *BB, uint32_t Freq) {
Freqs[BB] = Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
}
/// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
/// edge probability.
uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const {
BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
uint64_t N = Prob.getNumerator();
uint64_t D = Prob.getDenominator();
uint64_t Res = (N * getBlockFreq(Src)) / D;
assert(Res <= UINT32_MAX);
return (uint32_t) Res;
}
/// incBlockFreq - Increase BB block frequency by FREQ.
///
void incBlockFreq(BlockT *BB, uint32_t Freq) {
Freqs[BB] += Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
<< " --> " << Freqs[BB] << "\n");
}
/// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
///
void divBlockFreq(BlockT *BB, BranchProbability Prob) {
uint64_t N = Prob.getNumerator();
assert(N && "Illegal division by zero!");
uint64_t D = Prob.getDenominator();
uint64_t Freq = (Freqs[BB] * D) / N;
// Should we assert it?
if (Freq > UINT32_MAX)
Freq = UINT32_MAX;
Freqs[BB] = (uint32_t) Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
<< ") --> " << Freqs[BB] << "\n");
}
// All blocks in postorder.
std::vector<BlockT *> POT;
// Map Block -> Position in reverse-postorder list.
DenseMap<BlockT *, unsigned> RPO;
// Cycle Probability for each bloch.
DenseMap<BlockT *, uint32_t> CycleProb;
// (reverse-)postorder traversal iterators.
typedef typename std::vector<BlockT *>::iterator pot_iterator;
typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
pot_iterator pot_begin() { return POT.begin(); }
pot_iterator pot_end() { return POT.end(); }
rpot_iterator rpot_begin() { return POT.rbegin(); }
rpot_iterator rpot_end() { return POT.rend(); }
rpot_iterator rpot_at(BlockT *BB) {
rpot_iterator I = rpot_begin();
unsigned idx = RPO[BB];
assert(idx);
std::advance(I, idx - 1);
assert(*I == BB);
return I;
}
/// Return a probability of getting to the DST block through SRC->DST edge.
///
BranchProbability getBackEdgeProbability(BlockT *Src, BlockT *Dst) const {
uint32_t N = getEdgeFreq(Src, Dst);
uint32_t D = getBlockFreq(Dst);
return BranchProbability(N, D);
}
/// isReachable - Returns if BB block is reachable from the entry.
///
bool isReachable(BlockT *BB) {
return RPO.count(BB);
}
/// isBackedge - Return if edge Src -> Dst is a backedge.
///
bool isBackedge(BlockT *Src, BlockT *Dst) {
assert(isReachable(Src));
assert(isReachable(Dst));
unsigned a = RPO[Src];
unsigned b = RPO[Dst];
return a > b;
}
/// getSingleBlockPred - return single BB block predecessor or NULL if
/// BB has none or more predecessors.
BlockT *getSingleBlockPred(BlockT *BB) {
typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
if (PI == PE)
return 0;
BlockT *Pred = *PI;
++PI;
if (PI != PE)
return 0;
return Pred;
}
void doBlock(BlockT *BB, BlockT *LoopHead,
SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
setBlockFreq(BB, 0);
if (BB == LoopHead) {
setBlockFreq(BB, START_FREQ);
return;
}
if(BlockT *Pred = getSingleBlockPred(BB)) {
if (BlocksInLoop.count(Pred))
setBlockFreq(BB, getEdgeFreq(Pred, BB));
// TODO: else? irreducible, ignore it for now.
return;
}
bool isInLoop = false;
bool isLoopHead = false;
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
PI != PE; ++PI) {
BlockT *Pred = *PI;
if (isReachable(Pred) && isBackedge(Pred, BB)) {
isLoopHead = true;
} else if (BlocksInLoop.count(Pred)) {
incBlockFreq(BB, getEdgeFreq(Pred, BB));
isInLoop = true;
}
// TODO: else? irreducible.
}
if (!isInLoop)
return;
if (!isLoopHead)
return;
assert(START_FREQ >= CycleProb[BB]);
uint32_t CProb = CycleProb[BB];
uint32_t Numerator = START_FREQ - CProb ? START_FREQ - CProb : 1;
divBlockFreq(BB, BranchProbability(Numerator, START_FREQ));
}
/// doLoop - Propagate block frequency down throught the loop.
void doLoop(BlockT *Head, BlockT *Tail) {
DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
<< getBlockName(Tail) << ")\n");
SmallPtrSet<BlockT *, 8> BlocksInLoop;
for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) {
BlockT *BB = *I;
doBlock(BB, Head, BlocksInLoop);
BlocksInLoop.insert(BB);
}
// Compute loop's cyclic probability using backedges probabilities.
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
PI != PE; ++PI) {
BlockT *Pred = *PI;
assert(Pred);
if (isReachable(Pred) && isBackedge(Pred, Head)) {
BranchProbability Prob = getBackEdgeProbability(Pred, Head);
uint64_t N = Prob.getNumerator();
uint64_t D = Prob.getDenominator();
uint64_t Res = (N * START_FREQ) / D;
assert(Res <= UINT32_MAX);
CycleProb[Head] += (uint32_t) Res;
}
}
}
friend class BlockFrequency;
friend class MachineBlockFrequency;
void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
Fn = fn;
BPI = bpi;
// Clear everything.
RPO.clear();
POT.clear();
CycleProb.clear();
Freqs.clear();
BlockT *EntryBlock = fn->begin();
copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
unsigned RPOidx = 0;
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
BlockT *BB = *I;
RPO[BB] = ++RPOidx;
DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
}
// Travel over all blocks in postorder.
for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
BlockT *BB = *I;
BlockT *LastTail = 0;
DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
PI != PE; ++PI) {
BlockT *Pred = *PI;
if (isReachable(Pred) && isBackedge(Pred, BB)
&& (!LastTail || RPO[Pred] > RPO[LastTail]))
LastTail = Pred;
}
if (LastTail)
doLoop(BB, LastTail);
}
// At the end assume the whole function as a loop, and travel over it once
// again.
doLoop(*(rpot_begin()), *(pot_begin()));
}
public:
/// getBlockFreq - Return block frequency. Never return 0, value must be
/// positive.
uint32_t getBlockFreq(BlockT *BB) const {
typename DenseMap<BlockT *, uint32_t>::const_iterator I = Freqs.find(BB);
if (I != Freqs.end())
return I->second ? I->second : 1;
return 1;
}
void print(raw_ostream &OS) const {
OS << "\n\n---- Block Freqs ----\n";
for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
BlockT *BB = I++;
OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
for (typename GraphTraits<BlockT *>::ChildIteratorType
SI = GraphTraits<BlockT *>::child_begin(BB),
SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
BlockT *Succ = *SI;
OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ)
<< " = " << getEdgeFreq(BB, Succ) << "\n";
}
}
}
void dump() const {
print(dbgs());
}
};
}
#endif

View File

@ -15,8 +15,9 @@
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#include "llvm/InitializePasses.h" #include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/BranchProbability.h" #include "llvm/Support/BranchProbability.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm { namespace llvm {
@ -25,6 +26,11 @@ class raw_ostream;
class BranchProbabilityInfo : public FunctionPass { class BranchProbabilityInfo : public FunctionPass {
// Default weight value. Used when we don't have information about the edge. // Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
// the successors have a weight yet. But it doesn't make sense when providing
// weight to an edge that may have siblings with non-zero weights. This can
// be handled various ways, but it's probably fine for an edge with unknown
// weight to just "inherit" the non-zero weight of an adjacent successor.
static const uint32_t DEFAULT_WEIGHT = 16; static const uint32_t DEFAULT_WEIGHT = 16;
typedef std::pair<BasicBlock *, BasicBlock *> Edge; typedef std::pair<BasicBlock *, BasicBlock *> Edge;
@ -41,10 +47,7 @@ public:
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry()); initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
} }
void getAnalysisUsage(AnalysisUsage &AU) const { void getAnalysisUsage(AnalysisUsage &AU) const;
AU.addRequired<LoopInfo>();
AU.setPreservesAll();
}
bool runOnFunction(Function &F); bool runOnFunction(Function &F);

View File

@ -135,6 +135,7 @@ namespace llvm {
unsigned Flags); unsigned Flags);
/// createMemberType - Create debugging information entry for a member. /// createMemberType - Create debugging information entry for a member.
/// @param Scope Member scope.
/// @param Name Member name. /// @param Name Member name.
/// @param File File where this member is defined. /// @param File File where this member is defined.
/// @param LineNo Line number. /// @param LineNo Line number.
@ -143,7 +144,7 @@ namespace llvm {
/// @param OffsetInBits Member offset. /// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private /// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type. /// @param Ty Parent type.
DIType createMemberType(StringRef Name, DIFile File, DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
unsigned LineNo, uint64_t SizeInBits, unsigned LineNo, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty); unsigned Flags, DIType Ty);

View File

@ -37,8 +37,8 @@ class TargetData;
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
friend class IVUsers; friend class IVUsers;
public: public:
IVStrideUse(IVUsers *P, Instruction* U, Value *O, Value *PN) IVStrideUse(IVUsers *P, Instruction* U, Value *O)
: CallbackVH(U), Parent(P), OperandValToReplace(O), Phi(PN) { : CallbackVH(U), Parent(P), OperandValToReplace(O) {
} }
/// getUser - Return the user instruction for this use. /// getUser - Return the user instruction for this use.
@ -51,11 +51,6 @@ public:
setValPtr(NewUser); setValPtr(NewUser);
} }
/// getPhi - Return the phi node that represents this IV.
PHINode *getPhi() const {
return cast<PHINode>(Phi);
}
/// getOperandValToReplace - Return the Value of the operand in the user /// getOperandValToReplace - Return the Value of the operand in the user
/// instruction that this IVStrideUse is representing. /// instruction that this IVStrideUse is representing.
Value *getOperandValToReplace() const { Value *getOperandValToReplace() const {
@ -86,9 +81,6 @@ private:
/// that this IVStrideUse is representing. /// that this IVStrideUse is representing.
WeakVH OperandValToReplace; WeakVH OperandValToReplace;
/// Phi - The loop header phi that represents this IV.
WeakVH Phi;
/// PostIncLoops - The set of loops for which Expr has been adjusted to /// PostIncLoops - The set of loops for which Expr has been adjusted to
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
PostIncLoopSet PostIncLoops; PostIncLoopSet PostIncLoops;
@ -151,9 +143,9 @@ public:
/// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
/// reducible SCEV, recursively add its users to the IVUsesByStride set and /// reducible SCEV, recursively add its users to the IVUsesByStride set and
/// return true. Otherwise, return false. /// return true. Otherwise, return false.
bool AddUsersIfInteresting(Instruction *I, PHINode *Phi); bool AddUsersIfInteresting(Instruction *I);
IVStrideUse &AddUser(Instruction *User, Value *Operand, PHINode *Phi); IVStrideUse &AddUser(Instruction *User, Value *Operand);
/// getReplacementExpr - Return a SCEV expression which computes the /// getReplacementExpr - Return a SCEV expression which computes the
/// value of the OperandValToReplace of the given IVStrideUse. /// value of the OperandValToReplace of the given IVStrideUse.

View File

@ -90,18 +90,27 @@ namespace llvm {
/// get methods: These are static ctor methods for creating various /// get methods: These are static ctor methods for creating various
/// MemDepResult kinds. /// MemDepResult kinds.
static MemDepResult getDef(Instruction *Inst) { static MemDepResult getDef(Instruction *Inst) {
assert(Inst && "Def requires inst");
return MemDepResult(PairTy(Inst, Def)); return MemDepResult(PairTy(Inst, Def));
} }
static MemDepResult getClobber(Instruction *Inst) { static MemDepResult getClobber(Instruction *Inst) {
assert(Inst && "Clobber requires inst");
return MemDepResult(PairTy(Inst, Clobber)); return MemDepResult(PairTy(Inst, Clobber));
} }
static MemDepResult getNonLocal() { static MemDepResult getNonLocal() {
return MemDepResult(PairTy(0, NonLocal)); return MemDepResult(PairTy(0, NonLocal));
} }
static MemDepResult getUnknown() {
return MemDepResult(PairTy(0, Clobber));
}
/// isClobber - Return true if this MemDepResult represents a query that is /// isClobber - Return true if this MemDepResult represents a query that is
/// a instruction clobber dependency. /// a instruction clobber dependency.
bool isClobber() const { return Value.getInt() == Clobber; } bool isClobber() const { return Value.getInt() == Clobber && getInst(); }
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const { return Value.getInt() == Clobber && !getInst(); }
/// isDef - Return true if this MemDepResult represents a query that is /// isDef - Return true if this MemDepResult represents a query that is
/// a instruction definition dependency. /// a instruction definition dependency.

View File

@ -86,6 +86,13 @@ namespace llvm {
// //
ImmutablePass *createTypeBasedAliasAnalysisPass(); ImmutablePass *createTypeBasedAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
// alias analysis.
//
ImmutablePass *createObjCARCAliasAnalysisPass();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
// createProfileLoaderPass - This pass loads information from a profile dump // createProfileLoaderPass - This pass loads information from a profile dump

View File

@ -30,6 +30,10 @@ namespace llvm {
/// memory. /// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE; ScalarEvolution &SE;
// New instructions receive a name to identifies them with the current pass.
const char* IVName;
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions; InsertedExpressions;
std::set<AssertingVH<Value> > InsertedValues; std::set<AssertingVH<Value> > InsertedValues;
@ -67,9 +71,9 @@ namespace llvm {
public: public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode. /// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se) explicit SCEVExpander(ScalarEvolution &se, const char *name)
: SE(se), IVIncInsertLoop(0), CanonicalMode(true), : SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
Builder(se.getContext(), TargetFolder(se.TD)) {} CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {}
/// clear - Erase the contents of the InsertedExpressions map so that users /// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or /// trying to expand the same expression into multiple BasicBlocks or

View File

@ -15,6 +15,7 @@
#ifndef LLVM_ANALYSIS_VALUETRACKING_H #ifndef LLVM_ANALYSIS_VALUETRACKING_H
#define LLVM_ANALYSIS_VALUETRACKING_H #define LLVM_ANALYSIS_VALUETRACKING_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <string> #include <string>
@ -108,18 +109,9 @@ namespace llvm {
/// If InsertBefore is not null, this function will duplicate (modified) /// If InsertBefore is not null, this function will duplicate (modified)
/// insertvalues when a part of a nested struct is extracted. /// insertvalues when a part of a nested struct is extracted.
Value *FindInsertedValue(Value *V, Value *FindInsertedValue(Value *V,
const unsigned *idx_begin, ArrayRef<unsigned> idx_range,
const unsigned *idx_end,
Instruction *InsertBefore = 0); Instruction *InsertBefore = 0);
/// This is a convenience wrapper for finding values indexed by a single index
/// only.
inline Value *FindInsertedValue(Value *V, const unsigned Idx,
Instruction *InsertBefore = 0) {
const unsigned Idxs[1] = { Idx };
return FindInsertedValue(V, &Idxs[0], &Idxs[1], InsertBefore);
}
/// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
/// it can be expressed as a base pointer plus a constant offset. Return the /// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller. /// base and offset to the caller.
@ -158,6 +150,10 @@ namespace llvm {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup); return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
} }
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
} // end namespace llvm } // end namespace llvm
#endif #endif

View File

@ -17,52 +17,12 @@
#ifndef LLVM_ASSEMBLY_WRITER_H #ifndef LLVM_ASSEMBLY_WRITER_H
#define LLVM_ASSEMBLY_WRITER_H #define LLVM_ASSEMBLY_WRITER_H
#include <string>
namespace llvm { namespace llvm {
class Type; class Type;
class Module; class Module;
class Value; class Value;
class raw_ostream; class raw_ostream;
template <typename T> class SmallVectorImpl;
/// TypePrinting - Type printing machinery.
class TypePrinting {
void *TypeNames; // A map to remember type names.
TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT
void operator=(const TypePrinting&); // DO NOT IMPLEMENT
public:
TypePrinting();
~TypePrinting();
void clear();
void print(const Type *Ty, raw_ostream &OS, bool IgnoreTopLevelName = false);
void printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) {
print(Ty, OS, true);
}
/// hasTypeName - Return true if the type has a name in TypeNames, false
/// otherwise.
bool hasTypeName(const Type *Ty) const;
/// addTypeName - Add a name for the specified type if it doesn't already have
/// one. This name will be printed instead of the structural version of the
/// type in order to make the output more concise.
void addTypeName(const Type *Ty, const std::string &N);
private:
void CalcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack,
raw_ostream &OS, bool IgnoreTopLevelName = false);
};
// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
// type, if there is an entry in the Module's symbol table for the specified
// type or one of its component types.
//
void WriteTypeSymbolic(raw_ostream &, const Type *, const Module *M);
// WriteAsOperand - Write the name of the specified value out to the specified // WriteAsOperand - Write the name of the specified value out to the specified
// ostream. This can be useful when you just want to print int %reg126, not the // ostream. This can be useful when you just want to print int %reg126, not the

View File

@ -69,6 +69,9 @@ const Attributes Hotpatch = 1<<29; ///< Function should have special
///'hotpatch' sequence in prologue ///'hotpatch' sequence in prologue
const Attributes UWTable = 1<<30; ///< Function must be in a unwind const Attributes UWTable = 1<<30; ///< Function must be in a unwind
///table ///table
const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
/// Note that uwtable is about the ABI or the user mandating an entry in the /// Note that uwtable is about the ABI or the user mandating an entry in the
/// unwind table. The nounwind attribute is about an exception passing by the /// unwind table. The nounwind attribute is about an exception passing by the
@ -90,7 +93,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
Hotpatch | UWTable; Hotpatch | UWTable | NonLazyBind;
/// @brief Parameter attributes that do not apply to vararg call arguments. /// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet; const Attributes VarArgsIncompatible = StructRet;

View File

@ -110,7 +110,7 @@ public:
Function *getParent() { return Parent; } Function *getParent() { return Parent; }
/// use_back - Specialize the methods defined in Value, as we know that an /// use_back - Specialize the methods defined in Value, as we know that an
/// BasicBlock can only be used by Users (specifically PHI nodes, terminators, /// BasicBlock can only be used by Users (specifically terminators
/// and BlockAddress's). /// and BlockAddress's).
User *use_back() { return cast<User>(*use_begin());} User *use_back() { return cast<User>(*use_begin());}
const User *use_back() const { return cast<User>(*use_begin());} const User *use_back() const { return cast<User>(*use_begin());}
@ -138,6 +138,12 @@ public:
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg(); return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
} }
// Same as above, but also skip lifetime intrinsics.
Instruction* getFirstNonPHIOrDbgOrLifetime();
const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
}
/// removeFromParent - This method unlinks 'this' from the containing /// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it. /// function, but does not delete it.
/// ///
@ -248,6 +254,10 @@ public:
/// other than direct branches, switches, etc. to it. /// other than direct branches, switches, etc. to it.
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
/// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors
/// to refer to basic block New instead of to us.
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
private: private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
/// objects using it. This is almost always 0, sometimes one, possibly but /// objects using it. This is almost always 0, sometimes one, possibly but

View File

@ -194,6 +194,7 @@ public:
CurAbbrevs[i]->addRef(); CurAbbrevs[i]->addRef();
// Copy block scope and bump ref counts. // Copy block scope and bump ref counts.
BlockScope = RHS.BlockScope;
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
S != e; ++S) { S != e; ++S) {
std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
@ -375,10 +376,12 @@ public:
// Check that the block wasn't partially defined, and that the offset isn't // Check that the block wasn't partially defined, and that the offset isn't
// bogus. // bogus.
if (AtEndOfStream() || NextChar+NumWords*4 > BitStream->getLastChar()) const unsigned char *const SkipTo = NextChar + NumWords*4;
if (AtEndOfStream() || SkipTo > BitStream->getLastChar() ||
SkipTo < BitStream->getFirstChar())
return true; return true;
NextChar += NumWords*4; NextChar = SkipTo;
return false; return false;
} }

View File

@ -29,13 +29,23 @@ namespace bitc {
// Module sub-block id's. // Module sub-block id's.
PARAMATTR_BLOCK_ID, PARAMATTR_BLOCK_ID,
TYPE_BLOCK_ID,
/// TYPE_BLOCK_ID_OLD - This is the type descriptor block in LLVM 2.9 and
/// earlier, replaced with TYPE_BLOCK_ID2. FIXME: Remove in LLVM 3.1.
TYPE_BLOCK_ID_OLD,
CONSTANTS_BLOCK_ID, CONSTANTS_BLOCK_ID,
FUNCTION_BLOCK_ID, FUNCTION_BLOCK_ID,
TYPE_SYMTAB_BLOCK_ID,
/// TYPE_SYMTAB_BLOCK_ID_OLD - This type descriptor is from LLVM 2.9 and
/// earlier bitcode files. FIXME: Remove in LLVM 3.1
TYPE_SYMTAB_BLOCK_ID_OLD,
VALUE_SYMTAB_BLOCK_ID, VALUE_SYMTAB_BLOCK_ID,
METADATA_BLOCK_ID, METADATA_BLOCK_ID,
METADATA_ATTACHMENT_ID METADATA_ATTACHMENT_ID,
TYPE_BLOCK_ID_NEW
}; };
@ -72,31 +82,38 @@ namespace bitc {
/// TYPE blocks have codes for each type primitive they use. /// TYPE blocks have codes for each type primitive they use.
enum TypeCodes { enum TypeCodes {
TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
// Type Codes // Type Codes
TYPE_CODE_VOID = 2, // VOID TYPE_CODE_VOID = 2, // VOID
TYPE_CODE_FLOAT = 3, // FLOAT TYPE_CODE_FLOAT = 3, // FLOAT
TYPE_CODE_DOUBLE = 4, // DOUBLE TYPE_CODE_DOUBLE = 4, // DOUBLE
TYPE_CODE_LABEL = 5, // LABEL TYPE_CODE_LABEL = 5, // LABEL
TYPE_CODE_OPAQUE = 6, // OPAQUE TYPE_CODE_OPAQUE = 6, // OPAQUE
TYPE_CODE_INTEGER = 7, // INTEGER: [width] TYPE_CODE_INTEGER = 7, // INTEGER: [width]
TYPE_CODE_POINTER = 8, // POINTER: [pointee type] TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N] TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N]
TYPE_CODE_STRUCT = 10, // STRUCT: [ispacked, eltty x N]
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] // FIXME: This is the encoding used for structs in LLVM 2.9 and earlier.
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] // REMOVE this in LLVM 3.1
TYPE_CODE_STRUCT_OLD = 10, // STRUCT: [ispacked, eltty x N]
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
// These are not with the other floating point types because they're // These are not with the other floating point types because they're
// a late addition, and putting them in the right place breaks // a late addition, and putting them in the right place breaks
// binary compatibility. // binary compatibility.
TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
TYPE_CODE_METADATA = 16, // METADATA TYPE_CODE_METADATA = 16, // METADATA
TYPE_CODE_X86_MMX = 17 // X86 MMX TYPE_CODE_X86_MMX = 17, // X86 MMX
TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
TYPE_CODE_STRUCT_NAMED = 20 // STRUCT_NAMED: [ispacked, eltty x N]
}; };
// The type symbol table only has one code (TST_ENTRY_CODE). // The type symbol table only has one code (TST_ENTRY_CODE).
@ -112,20 +129,16 @@ namespace bitc {
enum MetadataCodes { enum MetadataCodes {
METADATA_STRING = 1, // MDSTRING: [values] METADATA_STRING = 1, // MDSTRING: [values]
// FIXME: Remove NODE in favor of NODE2 in LLVM 3.0 // 2 is unused.
METADATA_NODE = 2, // NODE with potentially invalid metadata // 3 is unused.
// FIXME: Remove FN_NODE in favor of FN_NODE2 in LLVM 3.0
METADATA_FN_NODE = 3, // FN_NODE with potentially invalid metadata
METADATA_NAME = 4, // STRING: [values] METADATA_NAME = 4, // STRING: [values]
// FIXME: Remove NAMED_NODE in favor of NAMED_NODE2 in LLVM 3.0 // 5 is unused.
METADATA_NAMED_NODE = 5, // NAMED_NODE with potentially invalid metadata
METADATA_KIND = 6, // [n x [id, name]] METADATA_KIND = 6, // [n x [id, name]]
// FIXME: Remove ATTACHMENT in favor of ATTACHMENT2 in LLVM 3.0 // 7 is unused.
METADATA_ATTACHMENT = 7, // ATTACHMENT with potentially invalid metadata METADATA_NODE = 8, // NODE: [n x (type num, value num)]
METADATA_NODE2 = 8, // NODE2: [n x (type num, value num)] METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)]
METADATA_FN_NODE2 = 9, // FN_NODE2: [n x (type num, value num)] METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
METADATA_NAMED_NODE2 = 10, // NAMED_NODE2: [n x mdnodes] METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]]
METADATA_ATTACHMENT2 = 11 // [m x [value, [n x [id, mdnode]]]
}; };
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
// constant and maintains an implicit current type value. // constant and maintains an implicit current type value.
@ -227,21 +240,18 @@ namespace bitc {
FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
FUNC_CODE_INST_MALLOC = 17, // MALLOC: [instty, op, align] // 17 is unused.
FUNC_CODE_INST_FREE = 18, // FREE: [opty, op] // 18 is unused.
FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align] FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
// FIXME: Remove STORE in favor of STORE2 in LLVM 3.0 // 21 is unused.
FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol] // 22 is unused.
// FIXME: Remove CALL in favor of CALL2 in LLVM 3.0
FUNC_CODE_INST_CALL = 22, // CALL with potentially invalid metadata
FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty] FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty]
// This store code encodes the pointer type, rather than the value type // This store code encodes the pointer type, rather than the value type
// this is so information only available in the pointer type (e.g. address // this is so information only available in the pointer type (e.g. address
// spaces) is retained. // spaces) is retained.
FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol] FUNC_CODE_INST_STORE = 24, // STORE: [ptrty,ptr,val, align, vol]
// FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0 // 25 is unused.
FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n]
FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands] FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands] FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands]
// fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to
@ -251,14 +261,12 @@ namespace bitc {
FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred]
FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...] FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
// 32 is unused.
// FIXME: Remove DEBUG_LOC in favor of DEBUG_LOC2 in LLVM 3.0
FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC with potentially invalid metadata
FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN
FUNC_CODE_INST_CALL2 = 34, // CALL2: [attr, fnty, fnid, args...] FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...]
FUNC_CODE_DEBUG_LOC2 = 35 // DEBUG_LOC2: [Line,Col,ScopeVal, IAVal] FUNC_CODE_DEBUG_LOC = 35 // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
}; };
} // End bitc namespace } // End bitc namespace
} // End llvm namespace } // End llvm namespace

View File

@ -16,6 +16,7 @@
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/InlineAsm.h" #include "llvm/InlineAsm.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/ISDOpcodes.h"
@ -37,6 +38,12 @@ unsigned ComputeLinearIndex(const Type *Ty,
const unsigned *IndicesEnd, const unsigned *IndicesEnd,
unsigned CurIndex = 0); unsigned CurIndex = 0);
inline unsigned ComputeLinearIndex(const Type *Ty,
ArrayRef<unsigned> Indices,
unsigned CurIndex = 0) {
return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
}
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of /// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
/// EVTs that represent all the individual underlying /// EVTs that represent all the individual underlying
/// non-aggregate types that comprise it. /// non-aggregate types that comprise it.

View File

@ -465,8 +465,8 @@ namespace llvm {
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB, const MachineBasicBlock *MBB,
unsigned uid) const; unsigned uid) const;
void EmitLLVMUsedList(Constant *List); void EmitLLVMUsedList(const Constant *List);
void EmitXXStructorList(Constant *List); void EmitXXStructorList(const Constant *List);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
}; };
} }

View File

@ -24,6 +24,7 @@
#ifndef NDEBUG #ifndef NDEBUG
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallSet.h"
#endif #endif
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
@ -57,7 +58,7 @@ public:
const Function *Fn; const Function *Fn;
MachineFunction *MF; MachineFunction *MF;
MachineRegisterInfo *RegInfo; MachineRegisterInfo *RegInfo;
BranchProbabilityInfo *BPI;
/// CanLowerReturn - true iff the function's return value can be lowered to /// CanLowerReturn - true iff the function's return value can be lowered to
/// registers. /// registers.
bool CanLowerReturn; bool CanLowerReturn;

View File

@ -232,7 +232,7 @@ namespace ISD {
SMULO, UMULO, SMULO, UMULO,
// Simple binary floating point operators. // Simple binary floating point operators.
FADD, FSUB, FMUL, FDIV, FREM, FADD, FSUB, FMUL, FMA, FDIV, FREM,
// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
// DAG node does not require that X and Y have the same type, just that they // DAG node does not require that X and Y have the same type, just that they
@ -580,7 +580,8 @@ namespace ISD {
// PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
// their first operand. The other operands are the address to prefetch, // their first operand. The other operands are the address to prefetch,
// read / write specifier, and locality specifier. // read / write specifier, locality specifier and instruction / data cache
// specifier.
PREFETCH, PREFETCH,
// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,

View File

@ -39,8 +39,6 @@ namespace {
(void) llvm::createGreedyRegisterAllocator(); (void) llvm::createGreedyRegisterAllocator();
(void) llvm::createDefaultPBQPRegisterAllocator(); (void) llvm::createDefaultPBQPRegisterAllocator();
(void) llvm::createSimpleRegisterCoalescer();
llvm::linkOcamlGC(); llvm::linkOcamlGC();
llvm::linkShadowStackGC(); llvm::linkShadowStackGC();

View File

@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/DataTypes.h"
#include <functional> #include <functional>
namespace llvm { namespace llvm {
@ -27,6 +28,7 @@ class MCSymbol;
class SlotIndexes; class SlotIndexes;
class StringRef; class StringRef;
class raw_ostream; class raw_ostream;
class MachineBranchProbabilityInfo;
template <> template <>
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> { struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
@ -63,12 +65,19 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
const BasicBlock *BB; const BasicBlock *BB;
int Number; int Number;
MachineFunction *xParent; MachineFunction *xParent;
/// Predecessors/Successors - Keep track of the predecessor / successor /// Predecessors/Successors - Keep track of the predecessor / successor
/// basicblocks. /// basicblocks.
std::vector<MachineBasicBlock *> Predecessors; std::vector<MachineBasicBlock *> Predecessors;
std::vector<MachineBasicBlock *> Successors; std::vector<MachineBasicBlock *> Successors;
/// Weights - Keep track of the weights to the successors. This vector
/// has the same order as Successors, or it is empty if we don't use it
/// (disable optimization).
std::vector<uint32_t> Weights;
typedef std::vector<uint32_t>::iterator weight_iterator;
/// LiveIns - Keep track of the physical registers that are livein of /// LiveIns - Keep track of the physical registers that are livein of
/// the basicblock. /// the basicblock.
std::vector<unsigned> LiveIns; std::vector<unsigned> LiveIns;
@ -244,11 +253,13 @@ public:
void updateTerminator(); void updateTerminator();
// Machine-CFG mutators // Machine-CFG mutators
/// addSuccessor - Add succ as a successor of this MachineBasicBlock. /// addSuccessor - Add succ as a successor of this MachineBasicBlock.
/// The Predecessors list of succ is automatically updated. /// The Predecessors list of succ is automatically updated. WEIGHT
/// parameter is stored in Weights list and it may be used by
/// MachineBranchProbabilityInfo analysis to calculate branch probability.
/// ///
void addSuccessor(MachineBasicBlock *succ); void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
/// removeSuccessor - Remove successor from the successors list of this /// removeSuccessor - Remove successor from the successors list of this
/// MachineBasicBlock. The Predecessors list of succ is automatically updated. /// MachineBasicBlock. The Predecessors list of succ is automatically updated.
@ -260,7 +271,12 @@ public:
/// updated. Return the iterator to the element after the one removed. /// updated. Return the iterator to the element after the one removed.
/// ///
succ_iterator removeSuccessor(succ_iterator I); succ_iterator removeSuccessor(succ_iterator I);
/// replaceSuccessor - Replace successor OLD with NEW and update weight info.
///
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
/// transferSuccessors - Transfers all the successors from MBB to this /// transferSuccessors - Transfers all the successors from MBB to this
/// machine basic block (i.e., copies all the successors fromMBB and /// machine basic block (i.e., copies all the successors fromMBB and
/// remove all the successors from fromMBB). /// remove all the successors from fromMBB).
@ -396,8 +412,22 @@ public:
/// getSymbol - Return the MCSymbol for this basic block. /// getSymbol - Return the MCSymbol for this basic block.
/// ///
MCSymbol *getSymbol() const; MCSymbol *getSymbol() const;
private: // Methods used to maintain doubly linked list of blocks...
private:
/// getWeightIterator - Return weight iterator corresponding to the I
/// successor iterator.
weight_iterator getWeightIterator(succ_iterator I);
friend class MachineBranchProbabilityInfo;
/// getSuccWeight - Return weight of the edge from this block to MBB. This
/// method should NOT be called directly, but by using getEdgeWeight method
/// from MachineBranchProbabilityInfo class.
uint32_t getSuccWeight(MachineBasicBlock *succ);
// Methods used to maintain doubly linked list of blocks...
friend struct ilist_traits<MachineBasicBlock>; friend struct ilist_traits<MachineBasicBlock>;
// Machine-CFG mutators // Machine-CFG mutators

View File

@ -0,0 +1,53 @@
//====----- MachineBlockFrequency.h - MachineBlock Frequency Analysis ----====//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loops should be simplified before this analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H
#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H
#include "llvm/CodeGen/MachineFunctionPass.h"
#include <climits>
namespace llvm {
class MachineBranchProbabilityInfo;
template<class BlockT, class FunctionT, class BranchProbInfoT>
class BlockFrequencyImpl;
/// MachineBlockFrequency pass uses BlockFrequencyImpl implementation to estimate
/// machine basic block frequencies.
class MachineBlockFrequency : public MachineFunctionPass {
BlockFrequencyImpl<MachineBasicBlock, MachineFunction, MachineBranchProbabilityInfo> *MBFI;
public:
static char ID;
MachineBlockFrequency();
~MachineBlockFrequency();
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnMachineFunction(MachineFunction &F);
/// getblockFreq - Return block frequency. Never return 0, value must be
/// positive. Please note that initial frequency is equal to 1024. It means
/// that we should not rely on the value itself, but only on the comparison to
/// the other block frequencies. We do this to avoid using of the floating
/// points.
uint32_t getBlockFreq(MachineBasicBlock *MBB);
};
}
#endif

View File

@ -0,0 +1,78 @@
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is used to evaluate branch probabilties on machine basic blocks.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
#include <climits>
namespace llvm {
class raw_ostream;
class MachineBasicBlock;
class MachineBranchProbabilityInfo : public ImmutablePass {
// Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
// the successors have a weight yet. But it doesn't make sense when providing
// weight to an edge that may have siblings with non-zero weights. This can
// be handled various ways, but it's probably fine for an edge with unknown
// weight to just "inherit" the non-zero weight of an adjacent successor.
static const uint32_t DEFAULT_WEIGHT = 16;
// Get sum of the block successors' weights.
uint32_t getSumForBlock(MachineBasicBlock *MBB) const;
public:
static char ID;
MachineBranchProbabilityInfo() : ImmutablePass(ID) {
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeMachineBranchProbabilityInfoPass(Registry);
}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
// Return edge weight. If we don't have any informations about it - return
// DEFAULT_WEIGHT.
uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
// A 'Hot' edge is an edge which probability is >= 80%.
bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
// Return a hot successor for the block BB or null if there isn't one.
MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
// Return a probability as a fraction between 0 (0% probability) and
// 1 (100% probability), however the value is never equal to 0, and can be 1
// only iff SRC block has only one successor.
BranchProbability getEdgeProbability(MachineBasicBlock *Src,
MachineBasicBlock *Dst) const;
// Print value between 0 (0% probability) and 1 (100% probability),
// however the value is never equal to 0, and can be 1 only iff SRC block
// has only one successor.
raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
MachineBasicBlock *Dst) const;
};
}
#endif

View File

@ -345,7 +345,7 @@ public:
/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead /// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
/// of `new MachineInstr'. /// of `new MachineInstr'.
/// ///
MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID, MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
DebugLoc DL, DebugLoc DL,
bool NoImp = false); bool NoImp = false);

View File

@ -17,11 +17,12 @@
#define LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H
#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineOperand.h"
#include "llvm/Target/TargetInstrDesc.h" #include "llvm/MC/MCInstrDesc.h"
#include "llvm/Target/TargetOpcodes.h" #include "llvm/Target/TargetOpcodes.h"
#include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/DebugLoc.h" #include "llvm/Support/DebugLoc.h"
#include <vector> #include <vector>
@ -30,7 +31,6 @@ namespace llvm {
template <typename T> class SmallVectorImpl; template <typename T> class SmallVectorImpl;
class AliasAnalysis; class AliasAnalysis;
class TargetInstrDesc;
class TargetInstrInfo; class TargetInstrInfo;
class TargetRegisterInfo; class TargetRegisterInfo;
class MachineFunction; class MachineFunction;
@ -57,7 +57,7 @@ public:
// function frame setup code. // function frame setup code.
}; };
private: private:
const TargetInstrDesc *TID; // Instruction descriptor. const MCInstrDesc *MCID; // Instruction descriptor.
uint16_t NumImplicitOps; // Number of implicit operands (which uint16_t NumImplicitOps; // Number of implicit operands (which
// are determined at construction time). // are determined at construction time).
@ -94,7 +94,7 @@ private:
MachineInstr(MachineFunction &, const MachineInstr &); MachineInstr(MachineFunction &, const MachineInstr &);
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
/// TID NULL and no operands. /// MCID NULL and no operands.
MachineInstr(); MachineInstr();
// The next two constructors have DebugLoc and non-DebugLoc versions; // The next two constructors have DebugLoc and non-DebugLoc versions;
@ -103,25 +103,25 @@ private:
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified /// implicit operands. It reserves space for the number of operands specified
/// by the TargetInstrDesc. The version with a DebugLoc should be preferred. /// by the MCInstrDesc. The version with a DebugLoc should be preferred.
explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false); explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that /// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic /// the MachineInstr is created and added to the end of the specified basic
/// block. The version with a DebugLoc should be preferred. /// block. The version with a DebugLoc should be preferred.
MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID);
/// MachineInstr ctor - This constructor create a MachineInstr and add the /// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by /// implicit operands. It reserves space for number of operands specified by
/// TargetInstrDesc. An explicit DebugLoc is supplied. /// MCInstrDesc. An explicit DebugLoc is supplied.
explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
bool NoImp = false); bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that /// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic /// the MachineInstr is created and added to the end of the specified basic
/// block. /// block.
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
const TargetInstrDesc &TID); const MCInstrDesc &MCID);
~MachineInstr(); ~MachineInstr();
@ -181,13 +181,22 @@ public:
/// ///
DebugLoc getDebugLoc() const { return debugLoc; } DebugLoc getDebugLoc() const { return debugLoc; }
/// emitError - Emit an error referring to the source location of this
/// instruction. This should only be used for inline assembly that is somehow
/// impossible to compile. Other errors should have been handled much
/// earlier.
///
/// If this method returns, the caller should try to recover from the error.
///
void emitError(StringRef Msg) const;
/// getDesc - Returns the target instruction descriptor of this /// getDesc - Returns the target instruction descriptor of this
/// MachineInstr. /// MachineInstr.
const TargetInstrDesc &getDesc() const { return *TID; } const MCInstrDesc &getDesc() const { return *MCID; }
/// getOpcode - Returns the opcode of this MachineInstr. /// getOpcode - Returns the opcode of this MachineInstr.
/// ///
int getOpcode() const { return TID->Opcode; } int getOpcode() const { return MCID->Opcode; }
/// Access to explicit operands of the instruction. /// Access to explicit operands of the instruction.
/// ///
@ -279,6 +288,9 @@ public:
bool isCopy() const { bool isCopy() const {
return getOpcode() == TargetOpcode::COPY; return getOpcode() == TargetOpcode::COPY;
} }
bool isFullCopy() const {
return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
}
/// isCopyLike - Return true if the instruction behaves like a copy. /// isCopyLike - Return true if the instruction behaves like a copy.
/// This does not include native copy instructions. /// This does not include native copy instructions.
@ -464,8 +476,8 @@ public:
/// hasUnmodeledSideEffects - Return true if this instruction has side /// hasUnmodeledSideEffects - Return true if this instruction has side
/// effects that are not modeled by mayLoad / mayStore, etc. /// effects that are not modeled by mayLoad / mayStore, etc.
/// For all instructions, the property is encoded in TargetInstrDesc::Flags /// For all instructions, the property is encoded in MCInstrDesc::Flags
/// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is
/// INLINEASM instruction, in which case the side effect property is encoded /// INLINEASM instruction, in which case the side effect property is encoded
/// in one of its operands (see InlineAsm::Extra_HasSideEffect). /// in one of its operands (see InlineAsm::Extra_HasSideEffect).
/// ///
@ -497,7 +509,7 @@ public:
/// setDesc - Replace the instruction descriptor (thus opcode) of /// setDesc - Replace the instruction descriptor (thus opcode) of
/// the current instruction with a new one. /// the current instruction with a new one.
/// ///
void setDesc(const TargetInstrDesc &tid) { TID = &tid; } void setDesc(const MCInstrDesc &tid) { MCID = &tid; }
/// setDebugLoc - Replace current source information with new such. /// setDebugLoc - Replace current source information with new such.
/// Avoid using this, the constructor argument is preferable. /// Avoid using this, the constructor argument is preferable.

View File

@ -22,7 +22,7 @@
namespace llvm { namespace llvm {
class TargetInstrDesc; class MCInstrDesc;
class MDNode; class MDNode;
namespace RegState { namespace RegState {
@ -77,6 +77,11 @@ public:
return *this; return *this;
} }
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
MI->addOperand(MachineOperand::CreateCImm(Val));
return *this;
}
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const { const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
MI->addOperand(MachineOperand::CreateFPImm(Val)); MI->addOperand(MachineOperand::CreateFPImm(Val));
return *this; return *this;
@ -175,8 +180,8 @@ public:
/// ///
inline MachineInstrBuilder BuildMI(MachineFunction &MF, inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID) { const MCInstrDesc &MCID) {
return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)); return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
} }
/// BuildMI - This version of the builder sets up the first operand as a /// BuildMI - This version of the builder sets up the first operand as a
@ -184,9 +189,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
/// ///
inline MachineInstrBuilder BuildMI(MachineFunction &MF, inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID, const MCInstrDesc &MCID,
unsigned DestReg) { unsigned DestReg) {
return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)) return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
.addReg(DestReg, RegState::Define); .addReg(DestReg, RegState::Define);
} }
@ -197,9 +202,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID, const MCInstrDesc &MCID,
unsigned DestReg) { unsigned DestReg) {
MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
BB.insert(I, MI); BB.insert(I, MI);
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
} }
@ -211,8 +216,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID) { const MCInstrDesc &MCID) {
MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
BB.insert(I, MI); BB.insert(I, MI);
return MachineInstrBuilder(MI); return MachineInstrBuilder(MI);
} }
@ -223,8 +228,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
/// ///
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID) { const MCInstrDesc &MCID) {
return BuildMI(*BB, BB->end(), DL, TID); return BuildMI(*BB, BB->end(), DL, MCID);
} }
/// BuildMI - This version of the builder inserts the newly-built /// BuildMI - This version of the builder inserts the newly-built
@ -233,9 +238,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
/// ///
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
DebugLoc DL, DebugLoc DL,
const TargetInstrDesc &TID, const MCInstrDesc &MCID,
unsigned DestReg) { unsigned DestReg) {
return BuildMI(*BB, BB->end(), DL, TID, DestReg); return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
} }
inline unsigned getDefRegState(bool B) { inline unsigned getDefRegState(bool B) {

View File

@ -21,6 +21,7 @@ namespace llvm {
class BlockAddress; class BlockAddress;
class ConstantFP; class ConstantFP;
class ConstantInt;
class GlobalValue; class GlobalValue;
class MachineBasicBlock; class MachineBasicBlock;
class MachineInstr; class MachineInstr;
@ -38,6 +39,7 @@ public:
enum MachineOperandType { enum MachineOperandType {
MO_Register, ///< Register operand. MO_Register, ///< Register operand.
MO_Immediate, ///< Immediate operand MO_Immediate, ///< Immediate operand
MO_CImmediate, ///< Immediate >64bit operand
MO_FPImmediate, ///< Floating-point immediate operand MO_FPImmediate, ///< Floating-point immediate operand
MO_MachineBasicBlock, ///< MachineBasicBlock reference MO_MachineBasicBlock, ///< MachineBasicBlock reference
MO_FrameIndex, ///< Abstract Stack Frame Index MO_FrameIndex, ///< Abstract Stack Frame Index
@ -111,6 +113,7 @@ private:
union { union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock. MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
const ConstantFP *CFP; // For MO_FPImmediate. const ConstantFP *CFP; // For MO_FPImmediate.
const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
int64_t ImmVal; // For MO_Immediate. int64_t ImmVal; // For MO_Immediate.
const MDNode *MD; // For MO_Metadata. const MDNode *MD; // For MO_Metadata.
MCSymbol *Sym; // For MO_MCSymbol MCSymbol *Sym; // For MO_MCSymbol
@ -173,6 +176,8 @@ public:
bool isReg() const { return OpKind == MO_Register; } bool isReg() const { return OpKind == MO_Register; }
/// isImm - Tests if this is a MO_Immediate operand. /// isImm - Tests if this is a MO_Immediate operand.
bool isImm() const { return OpKind == MO_Immediate; } bool isImm() const { return OpKind == MO_Immediate; }
/// isCImm - Test if t his is a MO_CImmediate operand.
bool isCImm() const { return OpKind == MO_CImmediate; }
/// isFPImm - Tests if this is a MO_FPImmediate operand. /// isFPImm - Tests if this is a MO_FPImmediate operand.
bool isFPImm() const { return OpKind == MO_FPImmediate; } bool isFPImm() const { return OpKind == MO_FPImmediate; }
/// isMBB - Tests if this is a MO_MachineBasicBlock operand. /// isMBB - Tests if this is a MO_MachineBasicBlock operand.
@ -333,6 +338,11 @@ public:
return Contents.ImmVal; return Contents.ImmVal;
} }
const ConstantInt *getCImm() const {
assert(isCImm() && "Wrong MachineOperand accessor");
return Contents.CI;
}
const ConstantFP *getFPImm() const { const ConstantFP *getFPImm() const {
assert(isFPImm() && "Wrong MachineOperand accessor"); assert(isFPImm() && "Wrong MachineOperand accessor");
return Contents.CFP; return Contents.CFP;
@ -440,6 +450,12 @@ public:
return Op; return Op;
} }
static MachineOperand CreateCImm(const ConstantInt *CI) {
MachineOperand Op(MachineOperand::MO_CImmediate);
Op.Contents.CI = CI;
return Op;
}
static MachineOperand CreateFPImm(const ConstantFP *CFP) { static MachineOperand CreateFPImm(const ConstantFP *CFP) {
MachineOperand Op(MachineOperand::MO_FPImmediate); MachineOperand Op(MachineOperand::MO_FPImmediate);
Op.Contents.CFP = CFP; Op.Contents.CFP = CFP;

View File

@ -32,11 +32,6 @@ class MachineRegisterInfo {
IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>, IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
VirtReg2IndexFunctor> VRegInfo; VirtReg2IndexFunctor> VRegInfo;
/// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to
/// virtual registers. For each target register class, it keeps a list of
/// virtual registers belonging to the class.
std::vector<unsigned> *RegClass2VRegMap;
/// RegAllocHints - This vector records register allocation hints for virtual /// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and hint type /// registers. For each virtual register, it keeps a register and hint type
/// pair making up the allocation hint. Hint type is target specific except /// pair making up the allocation hint. Hint type is target specific except
@ -216,13 +211,6 @@ public:
/// ///
unsigned getNumVirtRegs() const { return VRegInfo.size(); } unsigned getNumVirtRegs() const { return VRegInfo.size(); }
/// getRegClassVirtRegs - Return the list of virtual registers of the given
/// target register class.
const std::vector<unsigned> &
getRegClassVirtRegs(const TargetRegisterClass *RC) const {
return RegClass2VRegMap[RC->getID()];
}
/// setRegAllocationHint - Specify a register allocation hint for the /// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register. /// specified virtual register.
void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) { void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
@ -237,6 +225,14 @@ public:
return RegAllocHints[Reg]; return RegAllocHints[Reg];
} }
/// getSimpleHint - Return the preferred register allocation hint, or 0 if a
/// standard simple hint (Type == 0) is not set.
unsigned getSimpleHint(unsigned Reg) const {
std::pair<unsigned, unsigned> Hint = getRegAllocationHint(Reg);
return Hint.first ? 0 : Hint.second;
}
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Physical Register Use Info // Physical Register Use Info
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -73,16 +73,9 @@ namespace llvm {
/// This pass is still in development /// This pass is still in development
extern char &StrongPHIEliminationID; extern char &StrongPHIEliminationID;
extern char &PreAllocSplittingID;
/// LiveStacks pass. An analysis keeping track of the liveness of stack slots. /// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
extern char &LiveStacksID; extern char &LiveStacksID;
/// SimpleRegisterCoalescing pass. Aggressively coalesces every register
/// copy it can.
///
extern char &SimpleRegisterCoalescingID;
/// TwoAddressInstruction pass - This pass reduces two-address instructions to /// TwoAddressInstruction pass - This pass reduces two-address instructions to
/// use two operands. This destroys SSA information but it is desired by /// use two operands. This destroys SSA information but it is desired by
/// register allocators. /// register allocators.
@ -132,10 +125,10 @@ namespace llvm {
/// ///
FunctionPass *createDefaultPBQPRegisterAllocator(); FunctionPass *createDefaultPBQPRegisterAllocator();
/// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run /// RegisterCoalescer Pass - Coalesce all copies possible. Can run
/// independently of the register allocator. /// independently of the register allocator.
/// ///
RegisterCoalescer *createSimpleRegisterCoalescer(); RegisterCoalescer *createRegisterCoalescer();
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
/// and eliminates abstract frame references. /// and eliminates abstract frame references.

View File

@ -161,7 +161,8 @@ namespace llvm {
PBQP::PBQPNum benefit); PBQP::PBQPNum benefit);
}; };
FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder); FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder,
char *customPassID=0);
} }
#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */

View File

@ -1,244 +0,0 @@
//===-- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the abstract interface for register coalescers,
// allowing them to interact with and query register allocators.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/IncludeFile.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/ADT/SmallPtrSet.h"
#ifndef LLVM_CODEGEN_REGISTER_COALESCER_H
#define LLVM_CODEGEN_REGISTER_COALESCER_H
namespace llvm {
class MachineFunction;
class RegallocQuery;
class AnalysisUsage;
class MachineInstr;
class TargetRegisterInfo;
class TargetRegisterClass;
class TargetInstrInfo;
/// An abstract interface for register coalescers. Coalescers must
/// implement this interface to be part of the coalescer analysis
/// group.
class RegisterCoalescer {
public:
static char ID; // Class identification, replacement for typeinfo
RegisterCoalescer() {}
virtual ~RegisterCoalescer(); // We want to be subclassed
/// Run the coalescer on this function, providing interference
/// data to query. Return whether we removed any copies.
virtual bool coalesceFunction(MachineFunction &mf,
RegallocQuery &ifd) = 0;
/// Reset state. Can be used to allow a coalescer run by
/// PassManager to be run again by the register allocator.
virtual void reset(MachineFunction &mf) {}
/// Register allocators must call this from their own
/// getAnalysisUsage to cover the case where the coalescer is not
/// a Pass in the proper sense and isn't managed by PassManager.
/// PassManager needs to know which analyses to make available and
/// which to invalidate when running the register allocator or any
/// pass that might call coalescing. The long-term solution is to
/// allow hierarchies of PassManagers.
virtual void getAnalysisUsage(AnalysisUsage &AU) const {}
};
/// An abstract interface for register allocators to interact with
/// coalescers
///
/// Example:
///
/// This is simply an example of how to use the RegallocQuery
/// interface. It is not meant to be used in production.
///
/// class LinearScanRegallocQuery : public RegallocQuery {
/// private:
/// const LiveIntervals \&li;
///
/// public:
/// LinearScanRegallocQuery(LiveIntervals &intervals)
/// : li(intervals) {}
///
/// /// This is pretty slow and conservative, but since linear scan
/// /// allocation doesn't pre-compute interference information it's
/// /// the best we can do. Coalescers are always free to ignore this
/// /// and implement their own discovery strategy. See
/// /// SimpleRegisterCoalescing for an example.
/// void getInterferences(IntervalSet &interferences,
/// const LiveInterval &a) const {
/// for(LiveIntervals::const_iterator iv = li.begin(),
/// ivend = li.end();
/// iv != ivend;
/// ++iv) {
/// if (interfere(a, iv->second)) {
/// interferences.insert(&iv->second);
/// }
/// }
/// }
///
/// /// This is *really* slow and stupid. See above.
/// int getNumberOfInterferences(const LiveInterval &a) const {
/// IntervalSet intervals;
/// getInterferences(intervals, a);
/// return intervals.size();
/// }
/// };
///
/// In the allocator:
///
/// RegisterCoalescer &coalescer = getAnalysis<RegisterCoalescer>();
///
/// // We don't reset the coalescer so if it's already been run this
/// // takes almost no time.
/// LinearScanRegallocQuery ifd(*li_);
/// coalescer.coalesceFunction(fn, ifd);
///
class RegallocQuery {
public:
typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet;
virtual ~RegallocQuery() {}
/// Return whether two live ranges interfere.
virtual bool interfere(const LiveInterval &a,
const LiveInterval &b) const {
// A naive test
return a.overlaps(b);
}
/// Return the set of intervals that interfere with this one.
virtual void getInterferences(IntervalSet &interferences,
const LiveInterval &a) const = 0;
/// This can often be cheaper than actually returning the
/// interferences.
virtual int getNumberOfInterferences(const LiveInterval &a) const = 0;
/// Make any data structure updates necessary to reflect
/// coalescing or other modifications.
virtual void updateDataForMerge(const LiveInterval &a,
const LiveInterval &b,
const MachineInstr &copy) {}
/// Allow the register allocator to communicate when it doesn't
/// want a copy coalesced. This may be due to assumptions made by
/// the allocator about various invariants and so this question is
/// a matter of legality, not performance. Performance decisions
/// about which copies to coalesce should be made by the
/// coalescer.
virtual bool isLegalToCoalesce(const MachineInstr &inst) const {
return true;
}
};
/// CoalescerPair - A helper class for register coalescers. When deciding if
/// two registers can be coalesced, CoalescerPair can determine if a copy
/// instruction would become an identity copy after coalescing.
class CoalescerPair {
const TargetInstrInfo &tii_;
const TargetRegisterInfo &tri_;
/// dstReg_ - The register that will be left after coalescing. It can be a
/// virtual or physical register.
unsigned dstReg_;
/// srcReg_ - the virtual register that will be coalesced into dstReg.
unsigned srcReg_;
/// subReg_ - The subregister index of srcReg in dstReg_. It is possible the
/// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a
/// virtual register.
unsigned subIdx_;
/// partial_ - True when the original copy was a partial subregister copy.
bool partial_;
/// crossClass_ - True when both regs are virtual, and newRC is constrained.
bool crossClass_;
/// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy
/// instruction.
bool flipped_;
/// newRC_ - The register class of the coalesced register, or NULL if dstReg_
/// is a physreg.
const TargetRegisterClass *newRC_;
/// compose - Compose subreg indices a and b, either may be 0.
unsigned compose(unsigned, unsigned) const;
/// isMoveInstr - Return true if MI is a move or subreg instruction.
bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
unsigned &SrcSub, unsigned &DstSub) const;
public:
CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri)
: tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0),
partial_(false), crossClass_(false), flipped_(false), newRC_(0) {}
/// setRegisters - set registers to match the copy instruction MI. Return
/// false if MI is not a coalescable copy instruction.
bool setRegisters(const MachineInstr*);
/// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible
/// because dstReg_ is a physical register, or subIdx_ is set.
bool flip();
/// isCoalescable - Return true if MI is a copy instruction that will become
/// an identity copy after coalescing.
bool isCoalescable(const MachineInstr*) const;
/// isPhys - Return true if DstReg is a physical register.
bool isPhys() const { return !newRC_; }
/// isPartial - Return true if the original copy instruction did not copy the
/// full register, but was a subreg operation.
bool isPartial() const { return partial_; }
/// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's.
bool isCrossClass() const { return crossClass_; }
/// isFlipped - Return true when getSrcReg is the register being defined by
/// the original copy instruction.
bool isFlipped() const { return flipped_; }
/// getDstReg - Return the register (virtual or physical) that will remain
/// after coalescing.
unsigned getDstReg() const { return dstReg_; }
/// getSrcReg - Return the virtual register that will be coalesced away.
unsigned getSrcReg() const { return srcReg_; }
/// getSubIdx - Return the subregister index in DstReg that SrcReg will be
/// coalesced into, or 0.
unsigned getSubIdx() const { return subIdx_; }
/// getNewRC - Return the register class of the coalesced register.
const TargetRegisterClass *getNewRC() const { return newRC_; }
};
}
// Because of the way .a files work, we must force the SimpleRC
// implementation to be pulled in if the RegisterCoalescing header is
// included. Otherwise we run the risk of RegisterCoalescing being
// used, but the default implementation not being linked into the tool
// that uses it.
FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer)
FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing)
#endif

View File

@ -22,7 +22,7 @@ namespace RTLIB {
/// RTLIB::Libcall enum - This enum defines all of the runtime library calls /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
/// the backend can emit. The various long double types cannot be merged, /// the backend can emit. The various long double types cannot be merged,
/// because 80-bit library functions use "xf" and 128-bit use "tf". /// because 80-bit library functions use "xf" and 128-bit use "tf".
/// ///
/// When adding PPCF128 functions here, note that their names generally need /// When adding PPCF128 functions here, note that their names generally need
/// to be overridden for Darwin with the xxx$LDBL128 form. See /// to be overridden for Darwin with the xxx$LDBL128 form. See
/// PPCISelLowering.cpp. /// PPCISelLowering.cpp.
@ -46,6 +46,9 @@ namespace RTLIB {
MUL_I32, MUL_I32,
MUL_I64, MUL_I64,
MUL_I128, MUL_I128,
MULO_I32,
MULO_I64,
MULO_I128,
SDIV_I8, SDIV_I8,
SDIV_I16, SDIV_I16,
SDIV_I32, SDIV_I32,
@ -100,6 +103,10 @@ namespace RTLIB {
REM_F64, REM_F64,
REM_F80, REM_F80,
REM_PPCF128, REM_PPCF128,
FMA_F32,
FMA_F64,
FMA_F80,
FMA_PPCF128,
POWI_F32, POWI_F32,
POWI_F64, POWI_F64,
POWI_F80, POWI_F80,

View File

@ -34,7 +34,7 @@ namespace llvm {
class ScheduleDAG; class ScheduleDAG;
class SDNode; class SDNode;
class TargetInstrInfo; class TargetInstrInfo;
class TargetInstrDesc; class MCInstrDesc;
class TargetMachine; class TargetMachine;
class TargetRegisterClass; class TargetRegisterClass;
template<class Graph> class GraphWriter; template<class Graph> class GraphWriter;
@ -497,13 +497,19 @@ namespace llvm {
SUnit EntrySU; // Special node for the region entry. SUnit EntrySU; // Special node for the region entry.
SUnit ExitSU; // Special node for the region exit. SUnit ExitSU; // Special node for the region exit.
#ifdef NDEBUG
static const bool StressSched = false;
#else
bool StressSched;
#endif
explicit ScheduleDAG(MachineFunction &mf); explicit ScheduleDAG(MachineFunction &mf);
virtual ~ScheduleDAG(); virtual ~ScheduleDAG();
/// getInstrDesc - Return the TargetInstrDesc of this SUnit. /// getInstrDesc - Return the MCInstrDesc of this SUnit.
/// Return NULL for SDNodes without a machine opcode. /// Return NULL for SDNodes without a machine opcode.
const TargetInstrDesc *getInstrDesc(const SUnit *SU) const { const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
if (SU->isInstr()) return &SU->getInstr()->getDesc(); if (SU->isInstr()) return &SU->getInstr()->getDesc();
return getNodeDesc(SU->getNode()); return getNodeDesc(SU->getNode());
} }
@ -573,8 +579,8 @@ namespace llvm {
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap); void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
private: private:
// Return the TargetInstrDesc of this SDNode or NULL. // Return the MCInstrDesc of this SDNode or NULL.
const TargetInstrDesc *getNodeDesc(const SDNode *Node) const; const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
}; };
class SUnitIterator : public std::iterator<std::forward_iterator_tag, class SUnitIterator : public std::iterator<std::forward_iterator_tag,

View File

@ -25,7 +25,6 @@
namespace llvm { namespace llvm {
class InstrItineraryData; class InstrItineraryData;
class TargetInstrDesc;
class ScheduleDAG; class ScheduleDAG;
class SUnit; class SUnit;

View File

@ -96,8 +96,12 @@ public:
return DbgValues.empty() && ByvalParmDbgValues.empty(); return DbgValues.empty() && ByvalParmDbgValues.empty();
} }
SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) { ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
return DbgValMap[Node]; DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> >::iterator I =
DbgValMap.find(Node);
if (I != DbgValMap.end())
return I->second;
return ArrayRef<SDDbgValue*>();
} }
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator; typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
@ -898,7 +902,7 @@ public:
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
/// GetDbgValues - Get the debug values which reference the given SDNode. /// GetDbgValues - Get the debug values which reference the given SDNode.
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
return DbgInfo->getSDDbgValues(SD); return DbgInfo->getSDDbgValues(SD);
} }

View File

@ -23,6 +23,7 @@
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/ISDOpcodes.h"
@ -496,11 +497,29 @@ public:
/// ///
bool isOperandOf(SDNode *N) const; bool isOperandOf(SDNode *N) const;
/// isPredecessorOf - Return true if this node is a predecessor of N. This /// isPredecessorOf - Return true if this node is a predecessor of N.
/// node is either an operand of N or it can be reached by recursively /// NOTE: Implemented on top of hasPredecessor and every bit as
/// expensive. Use carefully.
bool isPredecessorOf(const SDNode *N) const { return N->hasPredecessor(this); }
/// hasPredecessor - Return true if N is a predecessor of this node.
/// N is either an operand of this node, or can be reached by recursively
/// traversing up the operands. /// traversing up the operands.
/// NOTE: this is an expensive method. Use it carefully. /// NOTE: This is an expensive method. Use it carefully.
bool isPredecessorOf(SDNode *N) const; bool hasPredecessor(const SDNode *N) const;
/// hasPredecesorHelper - Return true if N is a predecessor of this node.
/// N is either an operand of this node, or can be reached by recursively
/// traversing up the operands.
/// In this helper the Visited and worklist sets are held externally to
/// cache predecessors over multiple invocations. If you want to test for
/// multiple predecessors this method is preferable to multiple calls to
/// hasPredecessor. Be sure to clear Visited and Worklist if the DAG
/// changes.
/// NOTE: This is still very expensive. Use carefully.
bool hasPredecessorHelper(const SDNode *N,
SmallPtrSet<const SDNode *, 32> &Visited,
SmallVector<const SDNode *, 16> &Worklist) const;
/// getNumOperands - Return the number of values used by this operation. /// getNumOperands - Return the number of values used by this operation.
/// ///

View File

@ -140,6 +140,9 @@ namespace llvm {
return lie.getPointer(); return lie.getPointer();
} }
/// Return true for a valid index.
operator bool() const { return isValid(); }
/// Print this index to the given raw_ostream. /// Print this index to the given raw_ostream.
void print(raw_ostream &os) const; void print(raw_ostream &os) const;

View File

@ -52,7 +52,7 @@ protected:
const MCSection *MergeableConst8Section; const MCSection *MergeableConst8Section;
const MCSection *MergeableConst16Section; const MCSection *MergeableConst16Section;
public: public:
TargetLoweringObjectFileELF() {} TargetLoweringObjectFileELF();
~TargetLoweringObjectFileELF() {} ~TargetLoweringObjectFileELF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
@ -131,7 +131,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
const MCSection *LazySymbolPointerSection; const MCSection *LazySymbolPointerSection;
const MCSection *NonLazySymbolPointerSection; const MCSection *NonLazySymbolPointerSection;
public: public:
TargetLoweringObjectFileMachO() {} TargetLoweringObjectFileMachO();
~TargetLoweringObjectFileMachO() {} ~TargetLoweringObjectFileMachO() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
@ -207,7 +207,7 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
const MCSection *PDataSection; const MCSection *PDataSection;
const MCSection *XDataSection; const MCSection *XDataSection;
public: public:
TargetLoweringObjectFileCOFF() {} TargetLoweringObjectFileCOFF();
~TargetLoweringObjectFileCOFF() {} ~TargetLoweringObjectFileCOFF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);

View File

@ -83,7 +83,11 @@ namespace llvm {
isVoid = 35, // This has no value isVoid = 35, // This has no value
LAST_VALUETYPE = 36, // This always remains at the end of the list. untyped = 36, // This value takes a register, but has
// unspecified type. The register class
// will be determined by the opcode.
LAST_VALUETYPE = 37, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE. // This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors

View File

@ -1,10 +1,10 @@
//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===// //===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// Value types - These values correspond to the register types defined in the // Value types - These values correspond to the register types defined in the
@ -58,6 +58,7 @@ def v4f64 : ValueType<256, 32>; // 4 x f64 vector value
def x86mmx : ValueType<64 , 33>; // X86 MMX value def x86mmx : ValueType<64 , 33>; // X86 MMX value
def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue
def isVoid : ValueType<0 , 35>; // Produces no value def isVoid : ValueType<0 , 35>; // Produces no value
def untyped: ValueType<8 , 36>; // Produces an untyped value
def MetadataVT: ValueType<0, 250>; // Metadata def MetadataVT: ValueType<0, 250>; // Metadata

View File

@ -50,11 +50,11 @@ protected:
public: public:
/// isNullValue - Return true if this is the value that would be returned by /// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. /// getNullValue.
virtual bool isNullValue() const = 0; bool isNullValue() const;
/// isNegativeZeroValue - Return true if the value is what would be returned /// isNegativeZeroValue - Return true if the value is what would be returned
/// by getZeroValueForNegation. /// by getZeroValueForNegation.
virtual bool isNegativeZeroValue() const { return isNullValue(); } bool isNegativeZeroValue() const;
/// canTrap - Return true if evaluation of this constant could trap. This is /// canTrap - Return true if evaluation of this constant could trap. This is
/// true for things like constant expressions that could divide by zero. /// true for things like constant expressions that could divide by zero.

View File

@ -149,13 +149,7 @@ public:
static bool isValueValidForType(const Type *Ty, uint64_t V); static bool isValueValidForType(const Type *Ty, uint64_t V);
static bool isValueValidForType(const Type *Ty, int64_t V); static bool isValueValidForType(const Type *Ty, int64_t V);
/// This function will return true iff this constant represents the "null" bool isNegative() const { return Val.isNegative(); }
/// value that would be returned by the getNullValue method.
/// @returns true if this is the null integer value.
/// @brief Determine if the value is null.
virtual bool isNullValue() const {
return Val == 0;
}
/// This is just a convenience method to make client code smaller for a /// This is just a convenience method to make client code smaller for a
/// common code. It also correctly performs the comparison without the /// common code. It also correctly performs the comparison without the
@ -263,22 +257,14 @@ public:
/// isValueValidForType - return true if Ty is big enough to represent V. /// isValueValidForType - return true if Ty is big enough to represent V.
static bool isValueValidForType(const Type *Ty, const APFloat &V); static bool isValueValidForType(const Type *Ty, const APFloat &V);
inline const APFloat& getValueAPF() const { return Val; } inline const APFloat &getValueAPF() const { return Val; }
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. For ConstantFP, this is +0.0, but not -0.0. To handle the
/// two the same, use isZero().
virtual bool isNullValue() const;
/// isNegativeZeroValue - Return true if the value is what would be returned
/// by getZeroValueForNegation.
virtual bool isNegativeZeroValue() const {
return Val.isZero() && Val.isNegative();
}
/// isZero - Return true if the value is positive or negative zero. /// isZero - Return true if the value is positive or negative zero.
bool isZero() const { return Val.isZero(); } bool isZero() const { return Val.isZero(); }
/// isNegative - Return true if the sign bit is set.
bool isNegative() const { return Val.isNegative(); }
/// isNaN - Return true if the value is a NaN. /// isNaN - Return true if the value is a NaN.
bool isNaN() const { return Val.isNaN(); } bool isNaN() const { return Val.isNaN(); }
@ -324,10 +310,6 @@ protected:
public: public:
static ConstantAggregateZero* get(const Type *Ty); static ConstantAggregateZero* get(const Type *Ty);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return true; }
virtual void destroyConstant(); virtual void destroyConstant();
/// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -350,9 +332,7 @@ protected:
ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val); ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
public: public:
// ConstantArray accessors // ConstantArray accessors
static Constant *get(const ArrayType *T, const std::vector<Constant*> &V); static Constant *get(const ArrayType *T, ArrayRef<Constant*> V);
static Constant *get(const ArrayType *T, Constant *const *Vals,
unsigned NumVals);
/// This method constructs a ConstantArray and initializes it with a text /// This method constructs a ConstantArray and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to /// string. The default behavior (AddNull==true) causes a null terminator to
@ -389,10 +369,11 @@ public:
/// ///
std::string getAsString() const; std::string getAsString() const;
/// isNullValue - Return true if this is the value that would be returned by /// getAsCString - If this array is isCString(), then this method converts the
/// getNullValue. This always returns false because zero arrays are always /// array (without the trailing null byte) to an std::string and returns it.
/// created as ConstantAggregateZero objects. /// Otherwise, it asserts out.
virtual bool isNullValue() const { return false; } ///
std::string getAsCString() const;
virtual void destroyConstant(); virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@ -422,14 +403,29 @@ protected:
ConstantStruct(const StructType *T, const std::vector<Constant*> &Val); ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
public: public:
// ConstantStruct accessors // ConstantStruct accessors
static Constant *get(const StructType *T, const std::vector<Constant*> &V); static Constant *get(const StructType *T, ArrayRef<Constant*> V);
static Constant *get(LLVMContext &Context, static Constant *get(const StructType *T, ...) END_WITH_NULL;
const std::vector<Constant*> &V, bool Packed);
static Constant *get(LLVMContext &Context,
Constant *const *Vals, unsigned NumVals, bool Packed);
static Constant *get(LLVMContext &Context, bool Packed,
Constant * Val, ...) END_WITH_NULL;
/// getAnon - Return an anonymous struct that has the specified
/// elements. If the struct is possibly empty, then you must specify a
/// context.
static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) {
return get(getTypeForElements(V, Packed), V);
}
static Constant *getAnon(LLVMContext &Ctx,
ArrayRef<Constant*> V, bool Packed = false) {
return get(getTypeForElements(Ctx, V, Packed), V);
}
/// getTypeForElements - Return an anonymous struct type to use for a constant
/// with the specified set of elements. The list must not be empty.
static StructType *getTypeForElements(ArrayRef<Constant*> V,
bool Packed = false);
/// getTypeForElements - This version of the method allows an empty list.
static StructType *getTypeForElements(LLVMContext &Ctx,
ArrayRef<Constant*> V,
bool Packed = false);
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@ -439,13 +435,6 @@ public:
return reinterpret_cast<const StructType*>(Value::getType()); return reinterpret_cast<const StructType*>(Value::getType());
} }
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero structs are always
/// created as ConstantAggregateZero objects.
virtual bool isNullValue() const {
return false;
}
virtual void destroyConstant(); virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@ -476,8 +465,6 @@ protected:
public: public:
// ConstantVector accessors // ConstantVector accessors
static Constant *get(ArrayRef<Constant*> V); static Constant *get(ArrayRef<Constant*> V);
// FIXME: Eliminate this constructor form.
static Constant *get(const VectorType *T, const std::vector<Constant*> &V);
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@ -489,11 +476,6 @@ public:
return reinterpret_cast<const VectorType*>(Value::getType()); return reinterpret_cast<const VectorType*>(Value::getType());
} }
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero vectors are always
/// created as ConstantAggregateZero objects.
virtual bool isNullValue() const { return false; }
/// This function will return true iff every element in this vector constant /// This function will return true iff every element in this vector constant
/// is set to all ones. /// is set to all ones.
/// @returns true iff this constant's emements are all set to all ones. /// @returns true iff this constant's emements are all set to all ones.
@ -542,10 +524,6 @@ public:
/// get() - Static factory methods - Return objects of the specified value /// get() - Static factory methods - Return objects of the specified value
static ConstantPointerNull *get(const PointerType *T); static ConstantPointerNull *get(const PointerType *T);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return true; }
virtual void destroyConstant(); virtual void destroyConstant();
/// getType - Specialize the getType() method to always return an PointerType, /// getType - Specialize the getType() method to always return an PointerType,
@ -582,10 +560,6 @@ public:
Function *getFunction() const { return (Function*)Op<0>().get(); } Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return false; }
virtual void destroyConstant(); virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@ -623,35 +597,6 @@ protected:
setValueSubclassData(Opcode); setValueSubclassData(Opcode);
} }
// These private methods are used by the type resolution code to create
// ConstantExprs in intermediate forms.
static Constant *getTy(const Type *Ty, unsigned Opcode,
Constant *C1, Constant *C2,
unsigned Flags = 0);
static Constant *getCompareTy(unsigned short pred, Constant *C1,
Constant *C2);
static Constant *getSelectTy(const Type *Ty,
Constant *C1, Constant *C2, Constant *C3);
template<typename IndexTy>
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
IndexTy const *Idxs, unsigned NumIdxs,
bool InBounds);
static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
Constant *Idx);
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
Constant *Elt, Constant *Idx);
static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1,
Constant *V2, Constant *Mask);
static Constant *getExtractValueTy(const Type *Ty, Constant *Agg,
const unsigned *Idxs, unsigned NumIdxs);
static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
Constant *Val,
const unsigned *Idxs, unsigned NumIdxs);
template<typename IndexTy>
static Constant *getGetElementPtrImpl(Constant *C,
IndexTy const *IdxList,
unsigned NumIdx, bool InBounds);
public: public:
// Static methods to construct a ConstantExpr of different kinds. Note that // Static methods to construct a ConstantExpr of different kinds. Note that
// these methods may return a object that is not an instance of the // these methods may return a object that is not an instance of the
@ -822,9 +767,7 @@ public:
/// Select constant expr /// Select constant expr
/// ///
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) { static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
return getSelectTy(V1->getType(), C, V1, V2);
}
/// get - Return a binary or shift operator constant expression, /// get - Return a binary or shift operator constant expression,
/// folding if possible. /// folding if possible.
@ -846,7 +789,9 @@ public:
/// ///
static Constant *getGetElementPtr(Constant *C, static Constant *getGetElementPtr(Constant *C,
Constant *const *IdxList, unsigned NumIdx, Constant *const *IdxList, unsigned NumIdx,
bool InBounds = false); bool InBounds = false) {
return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds);
}
static Constant *getGetElementPtr(Constant *C, static Constant *getGetElementPtr(Constant *C,
Value *const *IdxList, unsigned NumIdx, Value *const *IdxList, unsigned NumIdx,
bool InBounds = false); bool InBounds = false);
@ -867,14 +812,9 @@ public:
static Constant *getExtractElement(Constant *Vec, Constant *Idx); static Constant *getExtractElement(Constant *Vec, Constant *Idx);
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx); static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask); static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
static Constant *getExtractValue(Constant *Agg, static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
const unsigned *IdxList, unsigned NumIdx);
static Constant *getInsertValue(Constant *Agg, Constant *Val, static Constant *getInsertValue(Constant *Agg, Constant *Val,
const unsigned *IdxList, unsigned NumIdx); ArrayRef<unsigned> Idxs);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return false; }
/// getOpcode - Return the opcode at the root of this constant expression /// getOpcode - Return the opcode at the root of this constant expression
unsigned getOpcode() const { return getSubclassDataFromValue(); } unsigned getOpcode() const { return getSubclassDataFromValue(); }
@ -895,10 +835,18 @@ public:
Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const; Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
/// getWithOperands - This returns the current constant expression with the /// getWithOperands - This returns the current constant expression with the
/// operands replaced with the specified values. The specified operands must /// operands replaced with the specified values. The specified array must
/// match count and type with the existing ones. /// have the same number of operands as our current one.
Constant *getWithOperands(ArrayRef<Constant*> Ops) const; Constant *getWithOperands(ArrayRef<Constant*> Ops) const {
return getWithOperands(Ops, getType());
}
/// getWithOperands - This returns the current constant expression with the
/// operands replaced with the specified values and with the specified result
/// type. The specified array must have the same number of operands as our
/// current one.
Constant *getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const;
virtual void destroyConstant(); virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@ -950,10 +898,6 @@ public:
/// ///
static UndefValue *get(const Type *T); static UndefValue *get(const Type *T);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return false; }
virtual void destroyConstant(); virtual void destroyConstant();
/// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:

View File

@ -29,7 +29,6 @@ extern unsigned char ConstantMergeID;
extern unsigned char CorrelatedValuePropagationID; extern unsigned char CorrelatedValuePropagationID;
extern unsigned char DeadArgEliminationID; extern unsigned char DeadArgEliminationID;
extern unsigned char DeadStoreEliminationID; extern unsigned char DeadStoreEliminationID;
extern unsigned char DeadTypeEliminationID;
extern unsigned char EarlyCSEID; extern unsigned char EarlyCSEID;
extern unsigned char FunctionAttrsID; extern unsigned char FunctionAttrsID;
extern unsigned char FunctionInliningID; extern unsigned char FunctionInliningID;

View File

@ -19,76 +19,27 @@
#define LLVM_DERIVED_TYPES_H #define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm { namespace llvm {
class Value; class Value;
template<class ValType, class TypeClass> class TypeMap;
class FunctionValType;
class ArrayValType;
class StructValType;
class PointerValType;
class VectorValType;
class IntegerValType;
class APInt; class APInt;
class LLVMContext; class LLVMContext;
template<typename T> class ArrayRef;
class DerivedType : public Type { class StringRef;
friend class Type;
protected:
explicit DerivedType(LLVMContext &C, TypeID id) : Type(C, id) {}
/// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
/// that the current type has transitioned from being abstract to being
/// concrete.
///
void notifyUsesThatTypeBecameConcrete();
/// dropAllTypeUses - When this (abstract) type is resolved to be equal to
/// another (more concrete) type, we must eliminate all references to other
/// types, to avoid some circular reference problems.
///
void dropAllTypeUses();
public:
//===--------------------------------------------------------------------===//
// Abstract Type handling methods - These types have special lifetimes, which
// are managed by (add|remove)AbstractTypeUser. See comments in
// AbstractTypeUser.h for more information.
/// refineAbstractTypeTo - This function is used to when it is discovered that
/// the 'this' abstract type is actually equivalent to the NewType specified.
/// This causes all users of 'this' to switch to reference the more concrete
/// type NewType and for 'this' to be deleted.
///
void refineAbstractTypeTo(const Type *NewType);
void dump() const { Type::dump(); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const DerivedType *) { return true; }
static inline bool classof(const Type *T) {
return T->isDerivedType();
}
};
/// Class to represent integer types. Note that this class is also used to /// Class to represent integer types. Note that this class is also used to
/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
/// Int64Ty. /// Int64Ty.
/// @brief Integer representation type /// @brief Integer representation type
class IntegerType : public DerivedType { class IntegerType : public Type {
friend class LLVMContextImpl; friend class LLVMContextImpl;
protected: protected:
explicit IntegerType(LLVMContext &C, unsigned NumBits) : explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){
DerivedType(C, IntegerTyID) {
setSubclassData(NumBits); setSubclassData(NumBits);
} }
friend class TypeMap<IntegerValType, IntegerType>;
public: public:
/// This enum is just used to hold constants we need for IntegerType. /// This enum is just used to hold constants we need for IntegerType.
enum { enum {
@ -103,7 +54,7 @@ public:
/// that instance will be returned. Otherwise a new one will be created. Only /// that instance will be returned. Otherwise a new one will be created. Only
/// one instance with a given NumBits value is ever created. /// one instance with a given NumBits value is ever created.
/// @brief Get or create an IntegerType instance. /// @brief Get or create an IntegerType instance.
static const IntegerType* get(LLVMContext &C, unsigned NumBits); static IntegerType *get(LLVMContext &C, unsigned NumBits);
/// @brief Get the number of bits in this IntegerType /// @brief Get the number of bits in this IntegerType
unsigned getBitWidth() const { return getSubclassData(); } unsigned getBitWidth() const { return getSubclassData(); }
@ -132,7 +83,7 @@ public:
/// @brief Is this a power-of-2 byte-width IntegerType ? /// @brief Is this a power-of-2 byte-width IntegerType ?
bool isPowerOf2ByteWidth() const; bool isPowerOf2ByteWidth() const;
// Methods for support type inquiry through isa, cast, and dyn_cast: // Methods for support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const IntegerType *) { return true; } static inline bool classof(const IntegerType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == IntegerTyID; return T->getTypeID() == IntegerTyID;
@ -142,34 +93,22 @@ public:
/// FunctionType - Class to represent function types /// FunctionType - Class to represent function types
/// ///
class FunctionType : public DerivedType { class FunctionType : public Type {
friend class TypeMap<FunctionValType, FunctionType>;
bool isVarArgs;
FunctionType(const FunctionType &); // Do not implement FunctionType(const FunctionType &); // Do not implement
const FunctionType &operator=(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement
FunctionType(const Type *Result, ArrayRef<const Type*> Params, FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
bool IsVarArgs);
public: public:
/// FunctionType::get - This static method is the primary way of constructing /// FunctionType::get - This static method is the primary way of constructing
/// a FunctionType. /// a FunctionType.
/// ///
static FunctionType *get( static FunctionType *get(const Type *Result,
const Type *Result, ///< The result type ArrayRef<Type*> Params, bool isVarArg);
ArrayRef<const Type*> Params, ///< The types of the parameters
bool isVarArg ///< Whether this is a variable argument length function
);
/// FunctionType::get - Create a FunctionType taking no parameters. /// FunctionType::get - Create a FunctionType taking no parameters.
/// ///
static FunctionType *get( static FunctionType *get(const Type *Result, bool isVarArg);
const Type *Result, ///< The result type
bool isVarArg ///< Whether this is a variable argument length function
) {
return get(Result, ArrayRef<const Type *>(), isVarArg);
}
/// isValidReturnType - Return true if the specified type is valid as a return /// isValidReturnType - Return true if the specified type is valid as a return
/// type. /// type.
static bool isValidReturnType(const Type *RetTy); static bool isValidReturnType(const Type *RetTy);
@ -178,26 +117,22 @@ public:
/// argument type. /// argument type.
static bool isValidArgumentType(const Type *ArgTy); static bool isValidArgumentType(const Type *ArgTy);
inline bool isVarArg() const { return isVarArgs; } bool isVarArg() const { return getSubclassData(); }
inline const Type *getReturnType() const { return ContainedTys[0]; } Type *getReturnType() const { return ContainedTys[0]; }
typedef Type::subtype_iterator param_iterator; typedef Type::subtype_iterator param_iterator;
param_iterator param_begin() const { return ContainedTys + 1; } param_iterator param_begin() const { return ContainedTys + 1; }
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
// Parameter type accessors... // Parameter type accessors.
const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
/// getNumParams - Return the number of fixed parameters this function type /// getNumParams - Return the number of fixed parameters this function type
/// requires. This does not consider varargs. /// requires. This does not consider varargs.
/// ///
unsigned getNumParams() const { return NumContainedTys - 1; } unsigned getNumParams() const { return NumContainedTys - 1; }
// Implement the AbstractTypeUser interface. // Methods for support type inquiry through isa, cast, and dyn_cast.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const FunctionType *) { return true; } static inline bool classof(const FunctionType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == FunctionTyID; return T->getTypeID() == FunctionTyID;
@ -206,22 +141,21 @@ public:
/// CompositeType - Common super class of ArrayType, StructType, PointerType /// CompositeType - Common super class of ArrayType, StructType, PointerType
/// and VectorType /// and VectorType.
class CompositeType : public DerivedType { class CompositeType : public Type {
protected: protected:
inline explicit CompositeType(LLVMContext &C, TypeID id) : explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { }
DerivedType(C, id) { }
public: public:
/// getTypeAtIndex - Given an index value into the type, return the type of /// getTypeAtIndex - Given an index value into the type, return the type of
/// the element. /// the element.
/// ///
virtual const Type *getTypeAtIndex(const Value *V) const = 0; Type *getTypeAtIndex(const Value *V) const;
virtual const Type *getTypeAtIndex(unsigned Idx) const = 0; Type *getTypeAtIndex(unsigned Idx) const;
virtual bool indexValid(const Value *V) const = 0; bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned Idx) const = 0; bool indexValid(unsigned Idx) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: // Methods for support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const CompositeType *) { return true; } static inline bool classof(const CompositeType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID || return T->getTypeID() == ArrayTyID ||
@ -232,69 +166,114 @@ public:
}; };
/// StructType - Class to represent struct types /// StructType - Class to represent struct types, both normal and packed.
/// Besides being optionally packed, structs can be either "anonymous" or may
/// have an identity. Anonymous structs are uniqued by structural equivalence,
/// but types are each unique when created, and optionally have a name.
/// ///
class StructType : public CompositeType { class StructType : public CompositeType {
friend class TypeMap<StructValType, StructType>;
StructType(const StructType &); // Do not implement StructType(const StructType &); // Do not implement
const StructType &operator=(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement
StructType(LLVMContext &C, ArrayRef<const Type*> Types, bool isPacked); StructType(LLVMContext &C)
: CompositeType(C, StructTyID), SymbolTableEntry(0) {}
enum {
// This is the contents of the SubClassData field.
SCDB_HasBody = 1,
SCDB_Packed = 2,
SCDB_IsAnonymous = 4
};
/// SymbolTableEntry - For a named struct that actually has a name, this is a
/// pointer to the symbol table entry (maintained by LLVMContext) for the
/// struct. This is null if the type is an anonymous struct or if it is
/// a named type that has an empty name.
///
void *SymbolTableEntry;
public: public:
~StructType() {
delete [] ContainedTys; // Delete the body.
}
/// StructType::createNamed - This creates a named struct with no body
/// specified. If the name is empty, it creates an unnamed struct, which has
/// a unique identity but no actual name.
static StructType *createNamed(LLVMContext &Context, StringRef Name);
static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements,
bool isPacked = false);
static StructType *createNamed(LLVMContext &Context, StringRef Name,
ArrayRef<Type*> Elements,
bool isPacked = false);
static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL;
/// StructType::get - This static method is the primary way to create a /// StructType::get - This static method is the primary way to create a
/// StructType. /// StructType.
/// static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
static StructType *get(LLVMContext &Context, bool isPacked = false);
ArrayRef<const Type*> Params,
bool isPacked=false);
/// StructType::get - Create an empty structure type. /// StructType::get - Create an empty structure type.
/// ///
static StructType *get(LLVMContext &Context, bool isPacked=false) { static StructType *get(LLVMContext &Context, bool isPacked = false);
return get(Context, llvm::ArrayRef<const Type*>(), isPacked);
} /// StructType::get - This static method is a convenience method for creating
/// structure types by specifying the elements as arguments. Note that this
/// method always returns a non-packed struct, and requires at least one
/// element type.
static StructType *get(Type *elt1, ...) END_WITH_NULL;
/// StructType::get - This static method is a convenience method for bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
/// creating structure types by specifying the elements as arguments.
/// Note that this method always returns a non-packed struct. To get /// isAnonymous - Return true if this type is uniqued by structural
/// an empty struct, pass NULL, NULL. /// equivalence, false if it has an identity.
static StructType *get(LLVMContext &Context, bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;}
const Type *type, ...) END_WITH_NULL;
/// isOpaque - Return true if this is a type with an identity that has no body
/// specified yet. These prints as 'opaque' in .ll files.
bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }
/// hasName - Return true if this is a named struct that has a non-empty name.
bool hasName() const { return SymbolTableEntry != 0; }
/// getName - Return the name for this struct type if it has an identity.
/// This may return an empty string for an unnamed struct type. Do not call
/// this on an anonymous type.
StringRef getName() const;
/// setName - Change the name of this type to the specified name, or to a name
/// with a suffix if there is a collision. Do not call this on an anonymous
/// type.
void setName(StringRef Name);
/// setBody - Specify a body for an opaque type.
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
void setBody(Type *elt1, ...) END_WITH_NULL;
/// isValidElementType - Return true if the specified type is valid as a /// isValidElementType - Return true if the specified type is valid as a
/// element type. /// element type.
static bool isValidElementType(const Type *ElemTy); static bool isValidElementType(const Type *ElemTy);
// Iterator access to the elements // Iterator access to the elements.
typedef Type::subtype_iterator element_iterator; typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; } element_iterator element_begin() const { return ContainedTys; }
element_iterator element_end() const { return &ContainedTys[NumContainedTys];} element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
/// isLayoutIdentical - Return true if this is layout identical to the
/// specified struct.
bool isLayoutIdentical(const StructType *Other) const;
// Random access to the elements // Random access to the elements
unsigned getNumElements() const { return NumContainedTys; } unsigned getNumElements() const { return NumContainedTys; }
const Type *getElementType(unsigned N) const { Type *getElementType(unsigned N) const {
assert(N < NumContainedTys && "Element number out of range!"); assert(N < NumContainedTys && "Element number out of range!");
return ContainedTys[N]; return ContainedTys[N];
} }
/// getTypeAtIndex - Given an index value into the type, return the type of // Methods for support type inquiry through isa, cast, and dyn_cast.
/// the element. For a structure type, this must be a constant value...
///
virtual const Type *getTypeAtIndex(const Value *V) const;
virtual const Type *getTypeAtIndex(unsigned Idx) const;
virtual bool indexValid(const Value *V) const;
virtual bool indexValid(unsigned Idx) const;
// Implement the AbstractTypeUser interface.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const StructType *) { return true; } static inline bool classof(const StructType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == StructTyID; return T->getTypeID() == StructTyID;
} }
bool isPacked() const { return (0 != getSubclassData()) ? true : false; }
}; };
/// SequentialType - This is the superclass of the array, pointer and vector /// SequentialType - This is the superclass of the array, pointer and vector
@ -306,38 +285,21 @@ public:
/// components out in memory identically. /// components out in memory identically.
/// ///
class SequentialType : public CompositeType { class SequentialType : public CompositeType {
PATypeHandle ContainedType; ///< Storage for the single contained type Type *ContainedType; ///< Storage for the single contained type.
SequentialType(const SequentialType &); // Do not implement! SequentialType(const SequentialType &); // Do not implement!
const SequentialType &operator=(const SequentialType &); // Do not implement! const SequentialType &operator=(const SequentialType &); // Do not implement!
// avoiding warning: 'this' : used in base member initializer list
SequentialType* this_() { return this; }
protected: protected:
SequentialType(TypeID TID, const Type *ElType) SequentialType(TypeID TID, Type *ElType)
: CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) { : CompositeType(ElType->getContext(), TID), ContainedType(ElType) {
ContainedTys = &ContainedType; ContainedTys = &ContainedType;
NumContainedTys = 1; NumContainedTys = 1;
} }
public: public:
inline const Type *getElementType() const { return ContainedTys[0]; } Type *getElementType() const { return ContainedTys[0]; }
virtual bool indexValid(const Value *V) const; // Methods for support type inquiry through isa, cast, and dyn_cast.
virtual bool indexValid(unsigned) const {
return true;
}
/// getTypeAtIndex - Given an index value into the type, return the type of
/// the element. For sequential types, there is only one subtype...
///
virtual const Type *getTypeAtIndex(const Value *) const {
return ContainedTys[0];
}
virtual const Type *getTypeAtIndex(unsigned) const {
return ContainedTys[0];
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SequentialType *) { return true; } static inline bool classof(const SequentialType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID || return T->getTypeID() == ArrayTyID ||
@ -347,15 +309,14 @@ public:
}; };
/// ArrayType - Class to represent array types /// ArrayType - Class to represent array types.
/// ///
class ArrayType : public SequentialType { class ArrayType : public SequentialType {
friend class TypeMap<ArrayValType, ArrayType>;
uint64_t NumElements; uint64_t NumElements;
ArrayType(const ArrayType &); // Do not implement ArrayType(const ArrayType &); // Do not implement
const ArrayType &operator=(const ArrayType &); // Do not implement const ArrayType &operator=(const ArrayType &); // Do not implement
ArrayType(const Type *ElType, uint64_t NumEl); ArrayType(Type *ElType, uint64_t NumEl);
public: public:
/// ArrayType::get - This static method is the primary way to construct an /// ArrayType::get - This static method is the primary way to construct an
/// ArrayType /// ArrayType
@ -366,31 +327,26 @@ public:
/// element type. /// element type.
static bool isValidElementType(const Type *ElemTy); static bool isValidElementType(const Type *ElemTy);
inline uint64_t getNumElements() const { return NumElements; } uint64_t getNumElements() const { return NumElements; }
// Implement the AbstractTypeUser interface. // Methods for support type inquiry through isa, cast, and dyn_cast.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const ArrayType *) { return true; } static inline bool classof(const ArrayType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID; return T->getTypeID() == ArrayTyID;
} }
}; };
/// VectorType - Class to represent vector types /// VectorType - Class to represent vector types.
/// ///
class VectorType : public SequentialType { class VectorType : public SequentialType {
friend class TypeMap<VectorValType, VectorType>;
unsigned NumElements; unsigned NumElements;
VectorType(const VectorType &); // Do not implement VectorType(const VectorType &); // Do not implement
const VectorType &operator=(const VectorType &); // Do not implement const VectorType &operator=(const VectorType &); // Do not implement
VectorType(const Type *ElType, unsigned NumEl); VectorType(Type *ElType, unsigned NumEl);
public: public:
/// VectorType::get - This static method is the primary way to construct an /// VectorType::get - This static method is the primary way to construct an
/// VectorType /// VectorType.
/// ///
static VectorType *get(const Type *ElementType, unsigned NumElements); static VectorType *get(const Type *ElementType, unsigned NumElements);
@ -400,7 +356,7 @@ public:
/// ///
static VectorType *getInteger(const VectorType *VTy) { static VectorType *getInteger(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
return VectorType::get(EltTy, VTy->getNumElements()); return VectorType::get(EltTy, VTy->getNumElements());
} }
@ -410,7 +366,7 @@ public:
/// ///
static VectorType *getExtendedElementVectorType(const VectorType *VTy) { static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
return VectorType::get(EltTy, VTy->getNumElements()); return VectorType::get(EltTy, VTy->getNumElements());
} }
@ -422,7 +378,7 @@ public:
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
assert((EltBits & 1) == 0 && assert((EltBits & 1) == 0 &&
"Cannot truncate vector element with odd bit-width"); "Cannot truncate vector element with odd bit-width");
const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
return VectorType::get(EltTy, VTy->getNumElements()); return VectorType::get(EltTy, VTy->getNumElements());
} }
@ -431,18 +387,14 @@ public:
static bool isValidElementType(const Type *ElemTy); static bool isValidElementType(const Type *ElemTy);
/// @brief Return the number of elements in the Vector type. /// @brief Return the number of elements in the Vector type.
inline unsigned getNumElements() const { return NumElements; } unsigned getNumElements() const { return NumElements; }
/// @brief Return the number of bits in the Vector type. /// @brief Return the number of bits in the Vector type.
inline unsigned getBitWidth() const { unsigned getBitWidth() const {
return NumElements * getElementType()->getPrimitiveSizeInBits(); return NumElements * getElementType()->getPrimitiveSizeInBits();
} }
// Implement the AbstractTypeUser interface. // Methods for support type inquiry through isa, cast, and dyn_cast.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const VectorType *) { return true; } static inline bool classof(const VectorType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == VectorTyID; return T->getTypeID() == VectorTyID;
@ -450,15 +402,12 @@ public:
}; };
/// PointerType - Class to represent pointers /// PointerType - Class to represent pointers.
/// ///
class PointerType : public SequentialType { class PointerType : public SequentialType {
friend class TypeMap<PointerValType, PointerType>;
unsigned AddressSpace;
PointerType(const PointerType &); // Do not implement PointerType(const PointerType &); // Do not implement
const PointerType &operator=(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement
explicit PointerType(const Type *ElType, unsigned AddrSpace); explicit PointerType(Type *ElType, unsigned AddrSpace);
public: public:
/// PointerType::get - This constructs a pointer to an object of the specified /// PointerType::get - This constructs a pointer to an object of the specified
/// type in a numbered address space. /// type in a numbered address space.
@ -475,39 +424,15 @@ public:
static bool isValidElementType(const Type *ElemTy); static bool isValidElementType(const Type *ElemTy);
/// @brief Return the address space of the Pointer type. /// @brief Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return AddressSpace; } inline unsigned getAddressSpace() const { return getSubclassData(); }
// Implement the AbstractTypeUser interface. // Implement support type inquiry through isa, cast, and dyn_cast.
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
virtual void typeBecameConcrete(const DerivedType *AbsTy);
// Implement support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const PointerType *) { return true; } static inline bool classof(const PointerType *) { return true; }
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == PointerTyID; return T->getTypeID() == PointerTyID;
} }
}; };
/// OpaqueType - Class to represent abstract types
///
class OpaqueType : public DerivedType {
friend class LLVMContextImpl;
OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
OpaqueType(LLVMContext &C);
public:
/// OpaqueType::get - Static factory method for the OpaqueType class...
///
static OpaqueType *get(LLVMContext &C);
// Implement support for type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const OpaqueType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == OpaqueTyID;
}
};
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -53,6 +53,7 @@ class RuntimeDyld {
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
// interface. // interface.
RuntimeDyldImpl *Dyld; RuntimeDyldImpl *Dyld;
RTDyldMemoryManager *MM;
public: public:
RuntimeDyld(RTDyldMemoryManager*); RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld(); ~RuntimeDyld();

View File

@ -128,8 +128,8 @@ public:
~Function(); ~Function();
const Type *getReturnType() const; // Return the type of the ret val Type *getReturnType() const; // Return the type of the ret val
const FunctionType *getFunctionType() const; // Return the FunctionType for me FunctionType *getFunctionType() const; // Return the FunctionType for me
/// getContext - Return a pointer to the LLVMContext associated with this /// getContext - Return a pointer to the LLVMContext associated with this
/// function, or NULL if this function is not bound to a context yet. /// function, or NULL if this function is not bound to a context yet.
@ -139,12 +139,6 @@ public:
/// arguments. /// arguments.
bool isVarArg() const; bool isVarArg() const;
/// isDeclaration - Is the body of this function unknown? (The basic block
/// list is empty if so.) This is true for function declarations, but not
/// true for function definitions.
///
virtual bool isDeclaration() const { return BasicBlocks.empty(); }
/// getIntrinsicID - This method returns the ID number of the specified /// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an /// function, or Intrinsic::not_intrinsic if the function is not an
/// instrinsic, or if the pointer is null. This value is always defined to be /// instrinsic, or if the pointer is null. This value is always defined to be

View File

@ -47,11 +47,6 @@ public:
/// Provide fast operand accessors /// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// isDeclaration - Is this global variable lacking an initializer? If so,
/// the global variable is defined in some other translation unit, and is thus
/// only a declaration here.
virtual bool isDeclaration() const;
/// removeFromParent - This method unlinks 'this' from the containing module, /// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it. /// but does not delete it.
/// ///
@ -63,23 +58,23 @@ public:
virtual void eraseFromParent(); virtual void eraseFromParent();
/// set/getAliasee - These methods retrive and set alias target. /// set/getAliasee - These methods retrive and set alias target.
void setAliasee(Constant* GV); void setAliasee(Constant *GV);
const Constant* getAliasee() const { const Constant *getAliasee() const {
return cast_or_null<Constant>(getOperand(0)); return cast_or_null<Constant>(getOperand(0));
} }
Constant* getAliasee() { Constant *getAliasee() {
return cast_or_null<Constant>(getOperand(0)); return cast_or_null<Constant>(getOperand(0));
} }
/// getAliasedGlobal() - Aliasee can be either global or bitcast of /// getAliasedGlobal() - Aliasee can be either global or bitcast of
/// global. This method retrives the global for both aliasee flavours. /// global. This method retrives the global for both aliasee flavours.
const GlobalValue* getAliasedGlobal() const; const GlobalValue *getAliasedGlobal() const;
/// resolveAliasedGlobal() - This method tries to ultimately resolve the alias /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias
/// by going through the aliasing chain and trying to find the very last /// by going through the aliasing chain and trying to find the very last
/// global. Returns NULL if a cycle was found. If stopOnWeak is false, then /// global. Returns NULL if a cycle was found. If stopOnWeak is false, then
/// the whole chain aliasing chain is traversed, otherwise - only strong /// the whole chain aliasing chain is traversed, otherwise - only strong
/// aliases. /// aliases.
const GlobalValue* resolveAliasedGlobal(bool stopOnWeak = true) const; const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: // Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalAlias *) { return true; } static inline bool classof(const GlobalAlias *) { return true; }

View File

@ -106,8 +106,8 @@ public:
bool use_empty_except_constants(); bool use_empty_except_constants();
/// getType - Global values are always pointers. /// getType - Global values are always pointers.
inline const PointerType *getType() const { inline PointerType *getType() const {
return reinterpret_cast<const PointerType*>(User::getType()); return reinterpret_cast<PointerType*>(User::getType());
} }
static LinkageTypes getLinkOnceLinkage(bool ODR) { static LinkageTypes getLinkOnceLinkage(bool ODR) {
@ -258,16 +258,12 @@ public:
/// @} /// @}
/// Override from Constant class. No GlobalValue's are null values so this
/// always returns false.
virtual bool isNullValue() const { return false; }
/// Override from Constant class. /// Override from Constant class.
virtual void destroyConstant(); virtual void destroyConstant();
/// isDeclaration - Return true if the primary definition of this global /// isDeclaration - Return true if the primary definition of this global
/// value is outside of the current translation unit... /// value is outside of the current translation unit.
virtual bool isDeclaration() const = 0; bool isDeclaration() const;
/// removeFromParent - This method unlinks 'this' from the containing module, /// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it. /// but does not delete it.

View File

@ -68,11 +68,6 @@ public:
/// Provide fast operand accessors /// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// isDeclaration - Is this global variable lacking an initializer? If so,
/// the global variable is defined in some other translation unit, and is thus
/// only a declaration here.
virtual bool isDeclaration() const { return getNumOperands() == 0; }
/// hasInitializer - Unless a global variable isExternal(), it has an /// hasInitializer - Unless a global variable isExternal(), it has an
/// initializer. The initializer for the global variable/constant is held by /// initializer. The initializer for the global variable/constant is held by
/// Initializer if an initializer is specified. /// Initializer if an initializer is specified.
@ -119,7 +114,7 @@ public:
/// illegal to call this method if the global is external, because we cannot /// illegal to call this method if the global is external, because we cannot
/// tell what the value is initialized to! /// tell what the value is initialized to!
/// ///
inline /*const FIXME*/ Constant *getInitializer() const { inline const Constant *getInitializer() const {
assert(hasInitializer() && "GV doesn't have initializer!"); assert(hasInitializer() && "GV doesn't have initializer!");
return static_cast<Constant*>(Op<0>().get()); return static_cast<Constant*>(Op<0>().get());
} }

View File

@ -65,6 +65,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeBasicCallGraphPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyPass(PassRegistry&);
void initializeBlockPlacementPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&);
void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&);
@ -83,7 +84,6 @@ void initializeDAEPass(PassRegistry&);
void initializeDAHPass(PassRegistry&); void initializeDAHPass(PassRegistry&);
void initializeDCEPass(PassRegistry&); void initializeDCEPass(PassRegistry&);
void initializeDSEPass(PassRegistry&); void initializeDSEPass(PassRegistry&);
void initializeDTEPass(PassRegistry&);
void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&);
void initializeDomOnlyPrinterPass(PassRegistry&); void initializeDomOnlyPrinterPass(PassRegistry&);
@ -140,10 +140,13 @@ void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&); void initializeLoopUnswitchPass(PassRegistry&);
void initializeLoopIdiomRecognizePass(PassRegistry&); void initializeLoopIdiomRecognizePass(PassRegistry&);
void initializeLowerAtomicPass(PassRegistry&); void initializeLowerAtomicPass(PassRegistry&);
void initializeLowerExpectIntrinsicPass(PassRegistry&);
void initializeLowerIntrinsicsPass(PassRegistry&); void initializeLowerIntrinsicsPass(PassRegistry&);
void initializeLowerInvokePass(PassRegistry&); void initializeLowerInvokePass(PassRegistry&);
void initializeLowerSetJmpPass(PassRegistry&); void initializeLowerSetJmpPass(PassRegistry&);
void initializeLowerSwitchPass(PassRegistry&); void initializeLowerSwitchPass(PassRegistry&);
void initializeMachineBlockFrequencyPass(PassRegistry&);
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
void initializeMachineCSEPass(PassRegistry&); void initializeMachineCSEPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&); void initializeMachineDominatorTreePass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&); void initializeMachineLICMPass(PassRegistry&);
@ -160,6 +163,10 @@ void initializeModuleDebugInfoPrinterPass(PassRegistry&);
void initializeNoAAPass(PassRegistry&); void initializeNoAAPass(PassRegistry&);
void initializeNoProfileInfoPass(PassRegistry&); void initializeNoProfileInfoPass(PassRegistry&);
void initializeNoPathProfileInfoPass(PassRegistry&); void initializeNoPathProfileInfoPass(PassRegistry&);
void initializeObjCARCAliasAnalysisPass(PassRegistry&);
void initializeObjCARCExpandPass(PassRegistry&);
void initializeObjCARCContractPass(PassRegistry&);
void initializeObjCARCOptPass(PassRegistry&);
void initializeOptimalEdgeProfilerPass(PassRegistry&); void initializeOptimalEdgeProfilerPass(PassRegistry&);
void initializeOptimizePHIsPass(PassRegistry&); void initializeOptimizePHIsPass(PassRegistry&);
void initializePEIPass(PassRegistry&); void initializePEIPass(PassRegistry&);
@ -171,7 +178,6 @@ void initializePostDomOnlyViewerPass(PassRegistry&);
void initializePostDomPrinterPass(PassRegistry&); void initializePostDomPrinterPass(PassRegistry&);
void initializePostDomViewerPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&);
void initializePostDominatorTreePass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&);
void initializePreAllocSplittingPass(PassRegistry&);
void initializePreVerifierPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&);
void initializePrintDbgInfoPass(PassRegistry&); void initializePrintDbgInfoPass(PassRegistry&);
void initializePrintFunctionPassPass(PassRegistry&); void initializePrintFunctionPassPass(PassRegistry&);
@ -192,7 +198,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&);
void initializeRegionOnlyViewerPass(PassRegistry&); void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&); void initializeRegionPrinterPass(PassRegistry&);
void initializeRegionViewerPass(PassRegistry&); void initializeRegionViewerPass(PassRegistry&);
void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
void initializeRenderMachineFunctionPass(PassRegistry&); void initializeRenderMachineFunctionPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&); void initializeSCCPPass(PassRegistry&);
void initializeSROA_DTPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&);
@ -200,7 +205,7 @@ void initializeSROA_SSAUpPass(PassRegistry&);
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
void initializeScalarEvolutionPass(PassRegistry&); void initializeScalarEvolutionPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&);
void initializeSimpleRegisterCoalescingPass(PassRegistry&); void initializeRegisterCoalescerPass(PassRegistry&);
void initializeSimplifyLibCallsPass(PassRegistry&); void initializeSimplifyLibCallsPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingPass(PassRegistry&); void initializeSinkingPass(PassRegistry&);

View File

@ -25,15 +25,16 @@ class PointerType;
class FunctionType; class FunctionType;
class Module; class Module;
struct InlineAsmKeyType; struct InlineAsmKeyType;
template<class ValType, class TypeClass, class ConstantClass, bool HasLargeKey> template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
bool HasLargeKey>
class ConstantUniqueMap; class ConstantUniqueMap;
template<class ConstantClass, class TypeClass, class ValType> template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator; struct ConstantCreator;
class InlineAsm : public Value { class InlineAsm : public Value {
friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>; friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
friend class ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm, friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
false>; PointerType, InlineAsm, false>;
InlineAsm(const InlineAsm &); // do not implement InlineAsm(const InlineAsm &); // do not implement
void operator=(const InlineAsm&); // do not implement void operator=(const InlineAsm&); // do not implement
@ -63,13 +64,13 @@ public:
/// getType - InlineAsm's are always pointers. /// getType - InlineAsm's are always pointers.
/// ///
const PointerType *getType() const { PointerType *getType() const {
return reinterpret_cast<const PointerType*>(Value::getType()); return reinterpret_cast<PointerType*>(Value::getType());
} }
/// getFunctionType - InlineAsm's are always pointers to functions. /// getFunctionType - InlineAsm's are always pointers to functions.
/// ///
const FunctionType *getFunctionType() const; FunctionType *getFunctionType() const;
const std::string &getAsmString() const { return AsmString; } const std::string &getAsmString() const { return AsmString; }
const std::string &getConstraintString() const { return Constraints; } const std::string &getConstraintString() const { return Constraints; }
@ -187,25 +188,32 @@ public:
// in the backend. // in the backend.
enum { enum {
// Fixed operands on an INLINEASM SDNode.
Op_InputChain = 0, Op_InputChain = 0,
Op_AsmString = 1, Op_AsmString = 1,
Op_MDNode = 2, Op_MDNode = 2,
Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
Op_FirstOperand = 4, Op_FirstOperand = 4,
// Fixed operands on an INLINEASM MachineInstr.
MIOp_AsmString = 0, MIOp_AsmString = 0,
MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
MIOp_FirstOperand = 2, MIOp_FirstOperand = 2,
// Interpretation of the MIOp_ExtraInfo bit field.
Extra_HasSideEffects = 1, Extra_HasSideEffects = 1,
Extra_IsAlignStack = 2, Extra_IsAlignStack = 2,
Kind_RegUse = 1, // Inline asm operands map to multiple SDNode / MachineInstr operands.
Kind_RegDef = 2, // The first operand is an immediate describing the asm operand, the low
Kind_Imm = 3, // bits is the kind:
Kind_Mem = 4, Kind_RegUse = 1, // Input register, "r".
Kind_RegDefEarlyClobber = 6, Kind_RegDef = 2, // Output register, "=r".
Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
Kind_Clobber = 4, // Clobbered register, "~r".
Kind_Imm = 5, // Immediate.
Kind_Mem = 6, // Memory operand, "m".
Flag_MatchingOperand = 0x80000000 Flag_MatchingOperand = 0x80000000
}; };
@ -232,7 +240,10 @@ public:
static bool isRegDefEarlyClobberKind(unsigned Flag) { static bool isRegDefEarlyClobberKind(unsigned Flag) {
return getKind(Flag) == Kind_RegDefEarlyClobber; return getKind(Flag) == Kind_RegDefEarlyClobber;
} }
static bool isClobberKind(unsigned Flag) {
return getKind(Flag) == Kind_Clobber;
}
/// getNumOperandRegisters - Extract the number of registers field from the /// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag. /// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) { static unsigned getNumOperandRegisters(unsigned Flag) {

View File

@ -20,6 +20,7 @@
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/Attributes.h" #include "llvm/Attributes.h"
#include "llvm/CallingConv.h" #include "llvm/CallingConv.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <iterator> #include <iterator>
@ -76,7 +77,7 @@ public:
/// getAllocatedType - Return the type that is being allocated by the /// getAllocatedType - Return the type that is being allocated by the
/// instruction. /// instruction.
/// ///
const Type *getAllocatedType() const; Type *getAllocatedType() const;
/// getAlignment - Return the alignment of the memory that is being allocated /// getAlignment - Return the alignment of the memory that is being allocated
/// by the instruction. /// by the instruction.
@ -271,10 +272,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
// GetElementPtrInst Class // GetElementPtrInst Class
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// checkType - Simple wrapper function to give a better assertion failure // checkGEPType - Simple wrapper function to give a better assertion failure
// message on bad indexes for a gep instruction. // message on bad indexes for a gep instruction.
// //
static inline const Type *checkType(const Type *Ty) { static inline const Type *checkGEPType(const Type *Ty) {
assert(Ty && "Invalid GetElementPtrInst indices for type!"); assert(Ty && "Invalid GetElementPtrInst indices for type!");
return Ty; return Ty;
} }
@ -315,13 +316,13 @@ class GetElementPtrInst : public Instruction {
/// pointer type. /// pointer type.
/// ///
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
static const Type *getIndexedType(const Type *Ptr, static Type *getIndexedType(const Type *Ptr,
RandomAccessIterator IdxBegin, RandomAccessIterator IdxBegin,
RandomAccessIterator IdxEnd, RandomAccessIterator IdxEnd,
// This argument ensures that we // This argument ensures that we
// have an iterator we can do // have an iterator we can do
// arithmetic on in constant time // arithmetic on in constant time
std::random_access_iterator_tag) { std::random_access_iterator_tag) {
unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd));
if (NumIdx > 0) if (NumIdx > 0)
@ -446,24 +447,22 @@ public:
/// pointer type. /// pointer type.
/// ///
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
static const Type *getIndexedType(const Type *Ptr, static Type *getIndexedType(const Type *Ptr, RandomAccessIterator IdxBegin,
RandomAccessIterator IdxBegin, RandomAccessIterator IdxEnd) {
RandomAccessIterator IdxEnd) {
return getIndexedType(Ptr, IdxBegin, IdxEnd, return getIndexedType(Ptr, IdxBegin, IdxEnd,
typename std::iterator_traits<RandomAccessIterator>:: typename std::iterator_traits<RandomAccessIterator>::
iterator_category()); iterator_category());
} }
static const Type *getIndexedType(const Type *Ptr, // FIXME: Use ArrayRef
Value* const *Idx, unsigned NumIdx); static Type *getIndexedType(const Type *Ptr,
Value* const *Idx, unsigned NumIdx);
static Type *getIndexedType(const Type *Ptr,
Constant* const *Idx, unsigned NumIdx);
static const Type *getIndexedType(const Type *Ptr, static Type *getIndexedType(const Type *Ptr,
Constant* const *Idx, unsigned NumIdx); uint64_t const *Idx, unsigned NumIdx);
static Type *getIndexedType(const Type *Ptr, Value *Idx);
static const Type *getIndexedType(const Type *Ptr,
uint64_t const *Idx, unsigned NumIdx);
static const Type *getIndexedType(const Type *Ptr, Value *Idx);
inline op_iterator idx_begin() { return op_begin()+1; } inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; }
@ -538,7 +537,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr,
unsigned Values, unsigned Values,
const Twine &NameStr, const Twine &NameStr,
Instruction *InsertBefore) Instruction *InsertBefore)
: Instruction(PointerType::get(checkType( : Instruction(PointerType::get(checkGEPType(
getIndexedType(Ptr->getType(), getIndexedType(Ptr->getType(),
IdxBegin, IdxEnd)), IdxBegin, IdxEnd)),
cast<PointerType>(Ptr->getType()) cast<PointerType>(Ptr->getType())
@ -557,7 +556,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr,
unsigned Values, unsigned Values,
const Twine &NameStr, const Twine &NameStr,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: Instruction(PointerType::get(checkType( : Instruction(PointerType::get(checkGEPType(
getIndexedType(Ptr->getType(), getIndexedType(Ptr->getType(),
IdxBegin, IdxEnd)), IdxBegin, IdxEnd)),
cast<PointerType>(Ptr->getType()) cast<PointerType>(Ptr->getType())
@ -843,46 +842,17 @@ public:
class CallInst : public Instruction { class CallInst : public Instruction {
AttrListPtr AttributeList; ///< parameter attributes for call AttrListPtr AttributeList; ///< parameter attributes for call
CallInst(const CallInst &CI); CallInst(const CallInst &CI);
void init(Value *Func, Value* const *Params, unsigned NumParams); void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
void init(Value *Func, Value *Actual1, Value *Actual2); void init(Value *Func, const Twine &NameStr);
void init(Value *Func, Value *Actual);
void init(Value *Func);
template<typename RandomAccessIterator> /// Construct a CallInst given a range of arguments.
void init(Value *Func,
RandomAccessIterator ArgBegin,
RandomAccessIterator ArgEnd,
const Twine &NameStr,
// This argument ensures that we have an iterator we can
// do arithmetic on in constant time
std::random_access_iterator_tag) {
unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
// This requires that the iterator points to contiguous memory.
init(Func, NumArgs ? &*ArgBegin : 0, NumArgs);
setName(NameStr);
}
/// Construct a CallInst given a range of arguments. RandomAccessIterator
/// must be a random-access iterator pointing to contiguous storage
/// (e.g. a std::vector<>::iterator). Checks are made for
/// random-accessness but not for contiguous storage as that would
/// incur runtime overhead.
/// @brief Construct a CallInst from a range of arguments /// @brief Construct a CallInst from a range of arguments
template<typename RandomAccessIterator> inline CallInst(Value *Func, ArrayRef<Value *> Args,
CallInst(Value *Func, const Twine &NameStr, Instruction *InsertBefore);
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
const Twine &NameStr, Instruction *InsertBefore);
/// Construct a CallInst given a range of arguments. RandomAccessIterator /// Construct a CallInst given a range of arguments.
/// must be a random-access iterator pointing to contiguous storage
/// (e.g. a std::vector<>::iterator). Checks are made for
/// random-accessness but not for contiguous storage as that would
/// incur runtime overhead.
/// @brief Construct a CallInst from a range of arguments /// @brief Construct a CallInst from a range of arguments
template<typename RandomAccessIterator> inline CallInst(Value *Func, ArrayRef<Value *> Args,
inline CallInst(Value *Func,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
const Twine &NameStr, BasicBlock *InsertAtEnd); const Twine &NameStr, BasicBlock *InsertAtEnd);
CallInst(Value *F, Value *Actual, const Twine &NameStr, CallInst(Value *F, Value *Actual, const Twine &NameStr,
@ -895,31 +865,18 @@ class CallInst : public Instruction {
protected: protected:
virtual CallInst *clone_impl() const; virtual CallInst *clone_impl() const;
public: public:
template<typename RandomAccessIterator>
static CallInst *Create(Value *Func, static CallInst *Create(Value *Func,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args,
RandomAccessIterator ArgEnd,
const Twine &NameStr = "", const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
return new(unsigned(ArgEnd - ArgBegin + 1)) return new(unsigned(Args.size() + 1))
CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertBefore); CallInst(Func, Args, NameStr, InsertBefore);
} }
template<typename RandomAccessIterator>
static CallInst *Create(Value *Func, static CallInst *Create(Value *Func,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args,
RandomAccessIterator ArgEnd,
const Twine &NameStr, BasicBlock *InsertAtEnd) { const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new(unsigned(ArgEnd - ArgBegin + 1)) return new(unsigned(Args.size() + 1))
CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertAtEnd); CallInst(Func, Args, NameStr, InsertAtEnd);
}
static CallInst *Create(Value *F, Value *Actual,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) {
return new(2) CallInst(F, Actual, NameStr, InsertBefore);
}
static CallInst *Create(Value *F, Value *Actual, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new(2) CallInst(F, Actual, NameStr, InsertAtEnd);
} }
static CallInst *Create(Value *F, const Twine &NameStr = "", static CallInst *Create(Value *F, const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
@ -1094,32 +1051,24 @@ template <>
struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> { struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> {
}; };
template<typename RandomAccessIterator> CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
CallInst::CallInst(Value *Func,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
const Twine &NameStr, BasicBlock *InsertAtEnd) const Twine &NameStr, BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(), ->getElementType())->getReturnType(),
Instruction::Call, Instruction::Call,
OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
unsigned(ArgEnd - ArgBegin + 1), InsertAtEnd) { unsigned(Args.size() + 1), InsertAtEnd) {
init(Func, ArgBegin, ArgEnd, NameStr, init(Func, Args, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
template<typename RandomAccessIterator> CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
CallInst::CallInst(Value *Func,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
const Twine &NameStr, Instruction *InsertBefore) const Twine &NameStr, Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(), ->getElementType())->getReturnType(),
Instruction::Call, Instruction::Call,
OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
unsigned(ArgEnd - ArgBegin + 1), InsertBefore) { unsigned(Args.size() + 1), InsertBefore) {
init(Func, ArgBegin, ArgEnd, NameStr, init(Func, Args, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
@ -1430,69 +1379,18 @@ class ExtractValueInst : public UnaryInstruction {
SmallVector<unsigned, 4> Indices; SmallVector<unsigned, 4> Indices;
ExtractValueInst(const ExtractValueInst &EVI); ExtractValueInst(const ExtractValueInst &EVI);
void init(const unsigned *Idx, unsigned NumIdx, void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
const Twine &NameStr);
void init(unsigned Idx, const Twine &NameStr);
template<typename RandomAccessIterator>
void init(RandomAccessIterator IdxBegin,
RandomAccessIterator IdxEnd,
const Twine &NameStr,
// This argument ensures that we have an iterator we can
// do arithmetic on in constant time
std::random_access_iterator_tag) {
unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd));
// There's no fundamental reason why we require at least one index
// (other than weirdness with &*IdxBegin being invalid; see
// getelementptr's init routine for example). But there's no
// present need to support it.
assert(NumIdx > 0 && "ExtractValueInst must have at least one index");
// This requires that the iterator points to contiguous memory.
init(&*IdxBegin, NumIdx, NameStr); // FIXME: for the general case
// we have to build an array here
}
/// getIndexedType - Returns the type of the element that would be extracted
/// with an extractvalue instruction with the specified parameters.
///
/// Null is returned if the indices are invalid for the specified type.
///
static const Type *getIndexedType(const Type *Agg,
const unsigned *Idx, unsigned NumIdx);
template<typename RandomAccessIterator>
static const Type *getIndexedType(const Type *Ptr,
RandomAccessIterator IdxBegin,
RandomAccessIterator IdxEnd,
// This argument ensures that we
// have an iterator we can do
// arithmetic on in constant time
std::random_access_iterator_tag) {
unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd));
if (NumIdx > 0)
// This requires that the iterator points to contiguous memory.
return getIndexedType(Ptr, &*IdxBegin, NumIdx);
else
return getIndexedType(Ptr, (const unsigned *)0, NumIdx);
}
/// Constructors - Create a extractvalue instruction with a base aggregate /// Constructors - Create a extractvalue instruction with a base aggregate
/// value and a list of indices. The first ctor can optionally insert before /// value and a list of indices. The first ctor can optionally insert before
/// an existing instruction, the second appends the new instruction to the /// an existing instruction, the second appends the new instruction to the
/// specified BasicBlock. /// specified BasicBlock.
template<typename RandomAccessIterator>
inline ExtractValueInst(Value *Agg, inline ExtractValueInst(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
Instruction *InsertBefore); Instruction *InsertBefore);
template<typename RandomAccessIterator>
inline ExtractValueInst(Value *Agg, inline ExtractValueInst(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, BasicBlock *InsertAtEnd); const Twine &NameStr, BasicBlock *InsertAtEnd);
// allocate space for exactly one operand // allocate space for exactly one operand
@ -1503,54 +1401,25 @@ protected:
virtual ExtractValueInst *clone_impl() const; virtual ExtractValueInst *clone_impl() const;
public: public:
template<typename RandomAccessIterator>
static ExtractValueInst *Create(Value *Agg, static ExtractValueInst *Create(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr = "", const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
return new return new
ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertBefore); ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
} }
template<typename RandomAccessIterator>
static ExtractValueInst *Create(Value *Agg, static ExtractValueInst *Create(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
BasicBlock *InsertAtEnd) { BasicBlock *InsertAtEnd) {
return new ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertAtEnd); return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd);
}
/// Constructors - These two creators are convenience methods because one
/// index extractvalue instructions are much more common than those with
/// more than one.
static ExtractValueInst *Create(Value *Agg, unsigned Idx,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) {
unsigned Idxs[1] = { Idx };
return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertBefore);
}
static ExtractValueInst *Create(Value *Agg, unsigned Idx,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
unsigned Idxs[1] = { Idx };
return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd);
} }
/// getIndexedType - Returns the type of the element that would be extracted /// getIndexedType - Returns the type of the element that would be extracted
/// with an extractvalue instruction with the specified parameters. /// with an extractvalue instruction with the specified parameters.
/// ///
/// Null is returned if the indices are invalid for the specified type. /// Null is returned if the indices are invalid for the specified type.
/// static Type *getIndexedType(const Type *Agg, ArrayRef<unsigned> Idxs);
template<typename RandomAccessIterator>
static const Type *getIndexedType(const Type *Ptr,
RandomAccessIterator IdxBegin,
RandomAccessIterator IdxEnd) {
return getIndexedType(Ptr, IdxBegin, IdxEnd,
typename std::iterator_traits<RandomAccessIterator>::
iterator_category());
}
static const Type *getIndexedType(const Type *Ptr, unsigned Idx);
typedef const unsigned* idx_iterator; typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_begin() const { return Indices.begin(); }
@ -1566,7 +1435,11 @@ public:
return 0U; // get index for modifying correct operand return 0U; // get index for modifying correct operand
} }
unsigned getNumIndices() const { // Note: always non-negative ArrayRef<unsigned> getIndices() const {
return Indices;
}
unsigned getNumIndices() const {
return (unsigned)Indices.size(); return (unsigned)Indices.size();
} }
@ -1584,31 +1457,21 @@ public:
} }
}; };
template<typename RandomAccessIterator>
ExtractValueInst::ExtractValueInst(Value *Agg, ExtractValueInst::ExtractValueInst(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
Instruction *InsertBefore) Instruction *InsertBefore)
: UnaryInstruction(checkType(getIndexedType(Agg->getType(), : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
IdxBegin, IdxEnd)),
ExtractValue, Agg, InsertBefore) { ExtractValue, Agg, InsertBefore) {
init(IdxBegin, IdxEnd, NameStr, init(Idxs, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
template<typename RandomAccessIterator>
ExtractValueInst::ExtractValueInst(Value *Agg, ExtractValueInst::ExtractValueInst(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: UnaryInstruction(checkType(getIndexedType(Agg->getType(), : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
IdxBegin, IdxEnd)),
ExtractValue, Agg, InsertAtEnd) { ExtractValue, Agg, InsertAtEnd) {
init(IdxBegin, IdxEnd, NameStr, init(Idxs, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
@ -1624,44 +1487,19 @@ class InsertValueInst : public Instruction {
void *operator new(size_t, unsigned); // Do not implement void *operator new(size_t, unsigned); // Do not implement
InsertValueInst(const InsertValueInst &IVI); InsertValueInst(const InsertValueInst &IVI);
void init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx, void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
const Twine &NameStr); const Twine &NameStr);
void init(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr);
template<typename RandomAccessIterator>
void init(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, RandomAccessIterator IdxEnd,
const Twine &NameStr,
// This argument ensures that we have an iterator we can
// do arithmetic on in constant time
std::random_access_iterator_tag) {
unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd));
// There's no fundamental reason why we require at least one index
// (other than weirdness with &*IdxBegin being invalid; see
// getelementptr's init routine for example). But there's no
// present need to support it.
assert(NumIdx > 0 && "InsertValueInst must have at least one index");
// This requires that the iterator points to contiguous memory.
init(Agg, Val, &*IdxBegin, NumIdx, NameStr); // FIXME: for the general case
// we have to build an array here
}
/// Constructors - Create a insertvalue instruction with a base aggregate /// Constructors - Create a insertvalue instruction with a base aggregate
/// value, a value to insert, and a list of indices. The first ctor can /// value, a value to insert, and a list of indices. The first ctor can
/// optionally insert before an existing instruction, the second appends /// optionally insert before an existing instruction, the second appends
/// the new instruction to the specified BasicBlock. /// the new instruction to the specified BasicBlock.
template<typename RandomAccessIterator>
inline InsertValueInst(Value *Agg, Value *Val, inline InsertValueInst(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
Instruction *InsertBefore); Instruction *InsertBefore);
template<typename RandomAccessIterator>
inline InsertValueInst(Value *Agg, Value *Val, inline InsertValueInst(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, BasicBlock *InsertAtEnd); const Twine &NameStr, BasicBlock *InsertAtEnd);
/// Constructors - These two constructors are convenience methods because one /// Constructors - These two constructors are convenience methods because one
@ -1679,37 +1517,17 @@ public:
return User::operator new(s, 2); return User::operator new(s, 2);
} }
template<typename RandomAccessIterator>
static InsertValueInst *Create(Value *Agg, Value *Val, static InsertValueInst *Create(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr = "", const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
NameStr, InsertBefore);
} }
template<typename RandomAccessIterator>
static InsertValueInst *Create(Value *Agg, Value *Val, static InsertValueInst *Create(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
BasicBlock *InsertAtEnd) { BasicBlock *InsertAtEnd) {
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd);
NameStr, InsertAtEnd);
}
/// Constructors - These two creators are convenience methods because one
/// index insertvalue instructions are much more common than those with
/// more than one.
static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) {
return new InsertValueInst(Agg, Val, Idx, NameStr, InsertBefore);
}
static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd);
} }
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
@ -1739,7 +1557,11 @@ public:
return 1U; // get index for modifying correct operand return 1U; // get index for modifying correct operand
} }
unsigned getNumIndices() const { // Note: always non-negative ArrayRef<unsigned> getIndices() const {
return Indices;
}
unsigned getNumIndices() const {
return (unsigned)Indices.size(); return (unsigned)Indices.size();
} }
@ -1762,33 +1584,25 @@ struct OperandTraits<InsertValueInst> :
public FixedNumOperandTraits<InsertValueInst, 2> { public FixedNumOperandTraits<InsertValueInst, 2> {
}; };
template<typename RandomAccessIterator>
InsertValueInst::InsertValueInst(Value *Agg, InsertValueInst::InsertValueInst(Value *Agg,
Value *Val, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
Instruction *InsertBefore) Instruction *InsertBefore)
: Instruction(Agg->getType(), InsertValue, : Instruction(Agg->getType(), InsertValue,
OperandTraits<InsertValueInst>::op_begin(this), OperandTraits<InsertValueInst>::op_begin(this),
2, InsertBefore) { 2, InsertBefore) {
init(Agg, Val, IdxBegin, IdxEnd, NameStr, init(Agg, Val, Idxs, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
template<typename RandomAccessIterator>
InsertValueInst::InsertValueInst(Value *Agg, InsertValueInst::InsertValueInst(Value *Agg,
Value *Val, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &NameStr, const Twine &NameStr,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: Instruction(Agg->getType(), InsertValue, : Instruction(Agg->getType(), InsertValue,
OperandTraits<InsertValueInst>::op_begin(this), OperandTraits<InsertValueInst>::op_begin(this),
2, InsertAtEnd) { 2, InsertAtEnd) {
init(Agg, Val, IdxBegin, IdxEnd, NameStr, init(Agg, Val, Idxs, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
@ -1814,7 +1628,7 @@ class PHINode : public Instruction {
explicit PHINode(const Type *Ty, unsigned NumReservedValues, explicit PHINode(const Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "", Instruction *InsertBefore = 0) const Twine &NameStr = "", Instruction *InsertBefore = 0)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
ReservedSpace(NumReservedValues * 2) { ReservedSpace(NumReservedValues) {
setName(NameStr); setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace); OperandList = allocHungoffUses(ReservedSpace);
} }
@ -1822,11 +1636,16 @@ class PHINode : public Instruction {
PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
ReservedSpace(NumReservedValues * 2) { ReservedSpace(NumReservedValues) {
setName(NameStr); setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace); OperandList = allocHungoffUses(ReservedSpace);
} }
protected: protected:
// allocHungoffUses - this is more complicated than the generic
// User::allocHungoffUses, because we have to allocate Uses for the incoming
// values and pointers to the incoming blocks, all in one allocation.
Use *allocHungoffUses(unsigned) const;
virtual PHINode *clone_impl() const; virtual PHINode *clone_impl() const;
public: public:
/// Constructors - NumReservedValues is a hint for the number of incoming /// Constructors - NumReservedValues is a hint for the number of incoming
@ -1845,32 +1664,55 @@ public:
/// Provide fast operand accessors /// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Block iterator interface. This provides access to the list of incoming
// basic blocks, which parallels the list of incoming values.
typedef BasicBlock **block_iterator;
typedef BasicBlock * const *const_block_iterator;
block_iterator block_begin() {
Use::UserRef *ref =
reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace);
return reinterpret_cast<block_iterator>(ref + 1);
}
const_block_iterator block_begin() const {
const Use::UserRef *ref =
reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace);
return reinterpret_cast<const_block_iterator>(ref + 1);
}
block_iterator block_end() {
return block_begin() + getNumOperands();
}
const_block_iterator block_end() const {
return block_begin() + getNumOperands();
}
/// getNumIncomingValues - Return the number of incoming edges /// getNumIncomingValues - Return the number of incoming edges
/// ///
unsigned getNumIncomingValues() const { return getNumOperands()/2; } unsigned getNumIncomingValues() const { return getNumOperands(); }
/// getIncomingValue - Return incoming value number x /// getIncomingValue - Return incoming value number x
/// ///
Value *getIncomingValue(unsigned i) const { Value *getIncomingValue(unsigned i) const {
assert(i*2 < getNumOperands() && "Invalid value number!"); return getOperand(i);
return getOperand(i*2);
} }
void setIncomingValue(unsigned i, Value *V) { void setIncomingValue(unsigned i, Value *V) {
assert(i*2 < getNumOperands() && "Invalid value number!"); setOperand(i, V);
setOperand(i*2, V);
} }
static unsigned getOperandNumForIncomingValue(unsigned i) { static unsigned getOperandNumForIncomingValue(unsigned i) {
return i*2; return i;
} }
static unsigned getIncomingValueNumForOperand(unsigned i) { static unsigned getIncomingValueNumForOperand(unsigned i) {
assert(i % 2 == 0 && "Invalid incoming-value operand index!"); return i;
return i/2;
} }
/// getIncomingBlock - Return incoming basic block number @p i. /// getIncomingBlock - Return incoming basic block number @p i.
/// ///
BasicBlock *getIncomingBlock(unsigned i) const { BasicBlock *getIncomingBlock(unsigned i) const {
return cast<BasicBlock>(getOperand(i*2+1)); return block_begin()[i];
} }
/// getIncomingBlock - Return incoming basic block corresponding /// getIncomingBlock - Return incoming basic block corresponding
@ -1878,7 +1720,7 @@ public:
/// ///
BasicBlock *getIncomingBlock(const Use &U) const { BasicBlock *getIncomingBlock(const Use &U) const {
assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?");
return cast<BasicBlock>((&U + 1)->get()); return getIncomingBlock(unsigned(&U - op_begin()));
} }
/// getIncomingBlock - Return incoming basic block corresponding /// getIncomingBlock - Return incoming basic block corresponding
@ -1889,16 +1731,8 @@ public:
return getIncomingBlock(I.getUse()); return getIncomingBlock(I.getUse());
} }
void setIncomingBlock(unsigned i, BasicBlock *BB) { void setIncomingBlock(unsigned i, BasicBlock *BB) {
setOperand(i*2+1, (Value*)BB); block_begin()[i] = BB;
}
static unsigned getOperandNumForIncomingBlock(unsigned i) {
return i*2+1;
}
static unsigned getIncomingBlockNumForOperand(unsigned i) {
assert(i % 2 == 1 && "Invalid incoming-block operand index!");
return i/2;
} }
/// addIncoming - Add an incoming value to the end of the PHI list /// addIncoming - Add an incoming value to the end of the PHI list
@ -1908,13 +1742,12 @@ public:
assert(BB && "PHI node got a null basic block!"); assert(BB && "PHI node got a null basic block!");
assert(getType() == V->getType() && assert(getType() == V->getType() &&
"All operands to PHI node must be the same type as the PHI node!"); "All operands to PHI node must be the same type as the PHI node!");
unsigned OpNo = NumOperands; if (NumOperands == ReservedSpace)
if (OpNo+2 > ReservedSpace)
growOperands(); // Get more space! growOperands(); // Get more space!
// Initialize some new operands. // Initialize some new operands.
NumOperands = OpNo+2; ++NumOperands;
OperandList[OpNo] = V; setIncomingValue(NumOperands - 1, V);
OperandList[OpNo+1] = (Value*)BB; setIncomingBlock(NumOperands - 1, BB);
} }
/// removeIncomingValue - Remove an incoming value. This is useful if a /// removeIncomingValue - Remove an incoming value. This is useful if a
@ -1937,14 +1770,16 @@ public:
/// block in the value list for this PHI. Returns -1 if no instance. /// block in the value list for this PHI. Returns -1 if no instance.
/// ///
int getBasicBlockIndex(const BasicBlock *BB) const { int getBasicBlockIndex(const BasicBlock *BB) const {
Use *OL = OperandList; for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) if (block_begin()[i] == BB)
if (OL[i+1].get() == (const Value*)BB) return i/2; return i;
return -1; return -1;
} }
Value *getIncomingValueForBlock(const BasicBlock *BB) const { Value *getIncomingValueForBlock(const BasicBlock *BB) const {
return getIncomingValue(getBasicBlockIndex(BB)); int Idx = getBasicBlockIndex(BB);
assert(Idx >= 0 && "Invalid basic block argument!");
return getIncomingValue(Idx);
} }
/// hasConstantValue - If the specified PHI node always merges together the /// hasConstantValue - If the specified PHI node always merges together the
@ -2397,71 +2232,39 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
class InvokeInst : public TerminatorInst { class InvokeInst : public TerminatorInst {
AttrListPtr AttributeList; AttrListPtr AttributeList;
InvokeInst(const InvokeInst &BI); InvokeInst(const InvokeInst &BI);
void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs);
template<typename RandomAccessIterator>
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, ArrayRef<Value *> Args, const Twine &NameStr);
const Twine &NameStr,
// This argument ensures that we have an iterator we can
// do arithmetic on in constant time
std::random_access_iterator_tag) {
unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
// This requires that the iterator points to contiguous memory.
init(Func, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs);
setName(NameStr);
}
/// Construct an InvokeInst given a range of arguments. /// Construct an InvokeInst given a range of arguments.
/// RandomAccessIterator must be a random-access iterator pointing to
/// contiguous storage (e.g. a std::vector<>::iterator). Checks are
/// made for random-accessness but not for contiguous storage as
/// that would incur runtime overhead.
/// ///
/// @brief Construct an InvokeInst from a range of arguments /// @brief Construct an InvokeInst from a range of arguments
template<typename RandomAccessIterator>
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, ArrayRef<Value *> Args, unsigned Values,
unsigned Values,
const Twine &NameStr, Instruction *InsertBefore); const Twine &NameStr, Instruction *InsertBefore);
/// Construct an InvokeInst given a range of arguments. /// Construct an InvokeInst given a range of arguments.
/// RandomAccessIterator must be a random-access iterator pointing to
/// contiguous storage (e.g. a std::vector<>::iterator). Checks are
/// made for random-accessness but not for contiguous storage as
/// that would incur runtime overhead.
/// ///
/// @brief Construct an InvokeInst from a range of arguments /// @brief Construct an InvokeInst from a range of arguments
template<typename RandomAccessIterator>
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, ArrayRef<Value *> Args, unsigned Values,
unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd); const Twine &NameStr, BasicBlock *InsertAtEnd);
protected: protected:
virtual InvokeInst *clone_impl() const; virtual InvokeInst *clone_impl() const;
public: public:
template<typename RandomAccessIterator>
static InvokeInst *Create(Value *Func, static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args, const Twine &NameStr = "",
RandomAccessIterator ArgEnd,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
unsigned Values(ArgEnd - ArgBegin + 3); unsigned Values = unsigned(Args.size()) + 3;
return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
Values, NameStr, InsertBefore); Values, NameStr, InsertBefore);
} }
template<typename RandomAccessIterator>
static InvokeInst *Create(Value *Func, static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args, const Twine &NameStr,
RandomAccessIterator ArgEnd,
const Twine &NameStr,
BasicBlock *InsertAtEnd) { BasicBlock *InsertAtEnd) {
unsigned Values(ArgEnd - ArgBegin + 3); unsigned Values = unsigned(Args.size()) + 3;
return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
Values, NameStr, InsertAtEnd); Values, NameStr, InsertAtEnd);
} }
@ -2627,37 +2430,27 @@ template <>
struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> { struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
}; };
template<typename RandomAccessIterator>
InvokeInst::InvokeInst(Value *Func, InvokeInst::InvokeInst(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args, unsigned Values,
RandomAccessIterator ArgEnd,
unsigned Values,
const Twine &NameStr, Instruction *InsertBefore) const Twine &NameStr, Instruction *InsertBefore)
: TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(), ->getElementType())->getReturnType(),
Instruction::Invoke, Instruction::Invoke,
OperandTraits<InvokeInst>::op_end(this) - Values, OperandTraits<InvokeInst>::op_end(this) - Values,
Values, InsertBefore) { Values, InsertBefore) {
init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, init(Func, IfNormal, IfException, Args, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
template<typename RandomAccessIterator>
InvokeInst::InvokeInst(Value *Func, InvokeInst::InvokeInst(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException, BasicBlock *IfNormal, BasicBlock *IfException,
RandomAccessIterator ArgBegin, ArrayRef<Value *> Args, unsigned Values,
RandomAccessIterator ArgEnd,
unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd) const Twine &NameStr, BasicBlock *InsertAtEnd)
: TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(), ->getElementType())->getReturnType(),
Instruction::Invoke, Instruction::Invoke,
OperandTraits<InvokeInst>::op_end(this) - Values, OperandTraits<InvokeInst>::op_end(this) - Values,
Values, InsertAtEnd) { Values, InsertAtEnd) {
init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, init(Func, IfNormal, IfException, Args, NameStr);
typename std::iterator_traits<RandomAccessIterator>
::iterator_category());
} }
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value)

View File

@ -16,6 +16,7 @@
#ifndef LLVM_INTRINSICS_H #ifndef LLVM_INTRINSICS_H
#define LLVM_INTRINSICS_H #define LLVM_INTRINSICS_H
#include "llvm/ADT/ArrayRef.h"
#include <string> #include <string>
namespace llvm { namespace llvm {
@ -44,12 +45,12 @@ namespace Intrinsic {
/// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
/// "llvm.ppc.altivec.lvx". /// "llvm.ppc.altivec.lvx".
std::string getName(ID id, const Type **Tys = 0, unsigned numTys = 0); std::string getName(ID id, ArrayRef<Type*> Tys = ArrayRef<Type*>());
/// Intrinsic::getType(ID) - Return the function type for an intrinsic. /// Intrinsic::getType(ID) - Return the function type for an intrinsic.
/// ///
const FunctionType *getType(LLVMContext &Context, ID id, const FunctionType *getType(LLVMContext &Context, ID id,
const Type **Tys = 0, unsigned numTys = 0); ArrayRef<Type*> Tys = ArrayRef<Type*>());
/// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be
/// overloaded. /// overloaded.
@ -67,8 +68,8 @@ namespace Intrinsic {
/// overloaded intrinsic, Tys should point to an array of numTys pointers to /// overloaded intrinsic, Tys should point to an array of numTys pointers to
/// Type, and must provide exactly one type for each overloaded type in the /// Type, and must provide exactly one type for each overloaded type in the
/// intrinsic. /// intrinsic.
Function *getDeclaration(Module *M, ID id, const Type **Tys = 0, Function *getDeclaration(Module *M, ID id,
unsigned numTys = 0); ArrayRef<Type*> Tys = ArrayRef<Type*>());
/// Map a GCC builtin name to an intrinsic ID. /// Map a GCC builtin name to an intrinsic ID.
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName); ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);

View File

@ -211,7 +211,8 @@ def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>,
// however it does conveniently prevent the prefetch from being reordered // however it does conveniently prevent the prefetch from being reordered
// with respect to nearby accesses to the same memory. // with respect to nearby accesses to the same memory.
def int_prefetch : Intrinsic<[], def int_prefetch : Intrinsic<[],
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty],
[IntrReadWriteArgMem, NoCapture<0>]>; [IntrReadWriteArgMem, NoCapture<0>]>;
def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>; def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;
@ -254,6 +255,12 @@ let Properties = [IntrReadMem] in {
def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
} }
let Properties = [IntrNoMem] in {
def int_fma : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
}
// NOTE: these are internal interfaces. // NOTE: these are internal interfaces.
def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>; def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
@ -265,6 +272,11 @@ def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
[IntrNoMem]>, [IntrNoMem]>,
GCCBuiltin<"__builtin_object_size">; GCCBuiltin<"__builtin_object_size">;
//===------------------------- Expect Intrinsics --------------------------===//
//
def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
//===-------------------- Bit Manipulation Intrinsics ---------------------===// //===-------------------- Bit Manipulation Intrinsics ---------------------===//
// //
@ -311,7 +323,7 @@ let Properties = [IntrNoMem] in {
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>;
} }
def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty], [IntrReadMem]>; def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>;
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;

View File

@ -39,7 +39,8 @@ public:
// compile-time performance optimization, not a correctness optimization. // compile-time performance optimization, not a correctness optimization.
enum { enum {
MD_dbg = 0, // "dbg" MD_dbg = 0, // "dbg"
MD_tbaa = 1 // "tbaa" MD_tbaa = 1, // "tbaa"
MD_prof = 2 // "prof"
}; };
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.

View File

@ -62,7 +62,6 @@ namespace {
(void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadCodeEliminationPass();
(void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadInstEliminationPass();
(void) llvm::createDeadStoreEliminationPass(); (void) llvm::createDeadStoreEliminationPass();
(void) llvm::createDeadTypeEliminationPass();
(void) llvm::createDomOnlyPrinterPass(); (void) llvm::createDomOnlyPrinterPass();
(void) llvm::createDomPrinterPass(); (void) llvm::createDomPrinterPass();
(void) llvm::createDomOnlyViewerPass(); (void) llvm::createDomOnlyViewerPass();
@ -92,11 +91,16 @@ namespace {
(void) llvm::createLoopUnswitchPass(); (void) llvm::createLoopUnswitchPass();
(void) llvm::createLoopIdiomPass(); (void) llvm::createLoopIdiomPass();
(void) llvm::createLoopRotatePass(); (void) llvm::createLoopRotatePass();
(void) llvm::createLowerExpectIntrinsicPass();
(void) llvm::createLowerInvokePass(); (void) llvm::createLowerInvokePass();
(void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSetJmpPass();
(void) llvm::createLowerSwitchPass(); (void) llvm::createLowerSwitchPass();
(void) llvm::createNoAAPass(); (void) llvm::createNoAAPass();
(void) llvm::createNoProfileInfoPass(); (void) llvm::createNoProfileInfoPass();
(void) llvm::createObjCARCAliasAnalysisPass();
(void) llvm::createObjCARCExpandPass();
(void) llvm::createObjCARCContractPass();
(void) llvm::createObjCARCOptPass();
(void) llvm::createProfileEstimatorPass(); (void) llvm::createProfileEstimatorPass();
(void) llvm::createProfileVerifierPass(); (void) llvm::createProfileVerifierPass();
(void) llvm::createPathProfileVerifierPass(); (void) llvm::createPathProfileVerifierPass();

View File

@ -37,6 +37,18 @@ namespace llvm {
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Properties to be set by the target writer, used to configure asm printer. // Properties to be set by the target writer, used to configure asm printer.
// //
/// PointerSize - Pointer size in bytes.
/// Default is 4.
unsigned PointerSize;
/// IsLittleEndian - True if target is little endian.
/// Default is true.
bool IsLittleEndian;
/// StackGrowsUp - True if target stack grow up.
/// Default is false.
bool StackGrowsUp;
/// HasSubsectionsViaSymbols - True if this target has the MachO /// HasSubsectionsViaSymbols - True if this target has the MachO
/// .subsections_via_symbols directive. /// .subsections_via_symbols directive.
@ -284,6 +296,10 @@ namespace llvm {
// use EmitLabelOffsetDifference. // use EmitLabelOffsetDifference.
bool DwarfUsesLabelOffsetForRanges; bool DwarfUsesLabelOffsetForRanges;
/// DwarfRegNumForCFI - True if dwarf register numbers are printed
/// instead of symbolic register names in .cfi_* directives.
bool DwarfRegNumForCFI; // Defaults to false;
//===--- CBE Asm Translation Table -----------------------------------===// //===--- CBE Asm Translation Table -----------------------------------===//
const char *const *AsmTransCBE; // Defaults to empty const char *const *AsmTransCBE; // Defaults to empty
@ -296,6 +312,21 @@ namespace llvm {
static unsigned getSLEB128Size(int Value); static unsigned getSLEB128Size(int Value);
static unsigned getULEB128Size(unsigned Value); static unsigned getULEB128Size(unsigned Value);
/// getPointerSize - Get the pointer size in bytes.
unsigned getPointerSize() const {
return PointerSize;
}
/// islittleendian - True if the target is little endian.
bool isLittleEndian() const {
return IsLittleEndian;
}
/// isStackGrowthDirectionUp - True if target stack grow up.
bool isStackGrowthDirectionUp() const {
return StackGrowsUp;
}
bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
// Data directive accessors. // Data directive accessors.
@ -475,6 +506,9 @@ namespace llvm {
bool doesDwarfUsesLabelOffsetForRanges() const { bool doesDwarfUsesLabelOffsetForRanges() const {
return DwarfUsesLabelOffsetForRanges; return DwarfUsesLabelOffsetForRanges;
} }
bool useDwarfRegNumForCFI() const {
return DwarfRegNumForCFI;
}
const char *const *getAsmCBE() const { const char *const *getAsmCBE() const {
return AsmTransCBE; return AsmTransCBE;
} }

View File

@ -39,6 +39,9 @@ namespace llvm {
class MCContext { class MCContext {
MCContext(const MCContext&); // DO NOT IMPLEMENT MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
public:
typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
private:
/// The MCAsmInfo for this target. /// The MCAsmInfo for this target.
const MCAsmInfo &MAI; const MCAsmInfo &MAI;
@ -52,7 +55,7 @@ namespace llvm {
BumpPtrAllocator Allocator; BumpPtrAllocator Allocator;
/// Symbols - Bindings of names to symbols. /// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*, BumpPtrAllocator&> Symbols; SymbolTable Symbols;
/// UsedNames - Keeps tracks of names that were used both for used declared /// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols. /// and artificial symbols.
@ -142,6 +145,14 @@ namespace llvm {
/// LookupSymbol - Get the symbol for \p Name, or null. /// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const; MCSymbol *LookupSymbol(StringRef Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
/// want to, for example, iterate over all symbols. 'const' because we
/// still want any modifications to the table itself to use the MCContext
/// APIs.
const SymbolTable &getSymbols() const {
return Symbols;
}
/// @} /// @}
/// @name Section Management /// @name Section Management

View File

@ -1,4 +1,4 @@
//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===// //===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -7,26 +7,23 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the TargetOperandInfo and TargetInstrDesc classes, which // This file defines the MCOperandInfo and MCInstrDesc classes, which
// are used to describe target instructions and their operands. // are used to describe target instructions and their operands.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_TARGETINSTRDESC_H #ifndef LLVM_MC_MCINSTRDESC_H
#define LLVM_TARGET_TARGETINSTRDESC_H #define LLVM_MC_MCINSTRDESC_H
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm { namespace llvm {
class TargetRegisterClass;
class TargetRegisterInfo;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Machine Operand Flags and Description // Machine Operand Flags and Description
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace TOI { namespace MCOI {
// Operand constraints // Operand constraints
enum OperandConstraint { enum OperandConstraint {
TIED_TO = 0, // Must be allocated the same register as. TIED_TO = 0, // Must be allocated the same register as.
@ -34,54 +31,57 @@ namespace TOI {
}; };
/// OperandFlags - These are flags set on operands, but should be considered /// OperandFlags - These are flags set on operands, but should be considered
/// private, all access should go through the TargetOperandInfo accessors. /// private, all access should go through the MCOperandInfo accessors.
/// See the accessors for a description of what these are. /// See the accessors for a description of what these are.
enum OperandFlags { enum OperandFlags {
LookupPtrRegClass = 0, LookupPtrRegClass = 0,
Predicate, Predicate,
OptionalDef OptionalDef
}; };
/// Operand Type - Operands are tagged with one of the values of this enum.
enum OperandType {
OPERAND_UNKNOWN,
OPERAND_IMMEDIATE,
OPERAND_REGISTER,
OPERAND_MEMORY,
OPERAND_PCREL
};
} }
/// TargetOperandInfo - This holds information about one operand of a machine /// MCOperandInfo - This holds information about one operand of a machine
/// instruction, indicating the register class for register operands, etc. /// instruction, indicating the register class for register operands, etc.
/// ///
class TargetOperandInfo { class MCOperandInfo {
public: public:
/// RegClass - This specifies the register class enumeration of the operand /// RegClass - This specifies the register class enumeration of the operand
/// if the operand is a register. If isLookupPtrRegClass is set, then this is /// if the operand is a register. If isLookupPtrRegClass is set, then this is
/// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
/// get a dynamic register class. /// get a dynamic register class.
///
/// NOTE: This member should be considered to be private, all access should go
/// through "getRegClass(TRI)" below.
short RegClass; short RegClass;
/// Flags - These are flags from the TOI::OperandFlags enum. /// Flags - These are flags from the MCOI::OperandFlags enum.
unsigned short Flags; unsigned short Flags;
/// Lower 16 bits are used to specify which constraints are set. The higher 16 /// Lower 16 bits are used to specify which constraints are set. The higher 16
/// bits are used to specify the value of constraints (4 bits each). /// bits are used to specify the value of constraints (4 bits each).
unsigned Constraints; unsigned Constraints;
/// OperandType - Information about the type of the operand.
MCOI::OperandType OperandType;
/// Currently no other information. /// Currently no other information.
/// getRegClass - Get the register class for the operand, handling resolution
/// of "symbolic" pointer register classes etc. If this is not a register
/// operand, this returns null.
const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const;
/// isLookupPtrRegClass - Set if this operand is a pointer value and it /// isLookupPtrRegClass - Set if this operand is a pointer value and it
/// requires a callback to look up its register class. /// requires a callback to look up its register class.
bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);} bool isLookupPtrRegClass() const { return Flags&(1 <<MCOI::LookupPtrRegClass);}
/// isPredicate - Set if this is one of the operands that made up of /// isPredicate - Set if this is one of the operands that made up of
/// the predicate operand that controls an isPredicable() instruction. /// the predicate operand that controls an isPredicable() instruction.
bool isPredicate() const { return Flags & (1 << TOI::Predicate); } bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
/// isOptionalDef - Set if this operand is a optional def. /// isOptionalDef - Set if this operand is a optional def.
/// ///
bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); } bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
}; };
@ -89,11 +89,11 @@ public:
// Machine Instruction Flags and Description // Machine Instruction Flags and Description
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// TargetInstrDesc flags - These should be considered private to the /// MCInstrDesc flags - These should be considered private to the
/// implementation of the TargetInstrDesc class. Clients should use the /// implementation of the MCInstrDesc class. Clients should use the predicate
/// predicate methods on TargetInstrDesc, not use these directly. These /// methods on MCInstrDesc, not use these directly. These all correspond to
/// all correspond to bitfields in the TargetInstrDesc::Flags field. /// bitfields in the MCInstrDesc::Flags field.
namespace TID { namespace MCID {
enum { enum {
Variadic = 0, Variadic = 0,
HasOptionalDef, HasOptionalDef,
@ -123,29 +123,29 @@ namespace TID {
}; };
} }
/// TargetInstrDesc - Describe properties that are true of each /// MCInstrDesc - Describe properties that are true of each instruction in the
/// instruction in the target description file. This captures information about /// target description file. This captures information about side effects,
/// side effects, register use and many other things. There is one instance of /// register use and many other things. There is one instance of this struct
/// this struct for each target instruction class, and the MachineInstr class /// for each target instruction class, and the MachineInstr class points to
/// points to this struct directly to describe itself. /// this struct directly to describe itself.
class TargetInstrDesc { class MCInstrDesc {
public: public:
unsigned short Opcode; // The opcode number unsigned short Opcode; // The opcode number
unsigned short NumOperands; // Num of args (may be more if variable_ops) unsigned short NumOperands; // Num of args (may be more if variable_ops)
unsigned short NumDefs; // Num of args that are definitions unsigned short NumDefs; // Num of args that are definitions
unsigned short SchedClass; // enum identifying instr sched class unsigned short SchedClass; // enum identifying instr sched class
unsigned short Size; // Number of bytes in encoding.
const char * Name; // Name of the instruction record in td file const char * Name; // Name of the instruction record in td file
unsigned Flags; // Flags identifying machine instr class unsigned Flags; // Flags identifying machine instr class
uint64_t TSFlags; // Target Specific Flag values uint64_t TSFlags; // Target Specific Flag values
const unsigned *ImplicitUses; // Registers implicitly read by this instr const unsigned *ImplicitUses; // Registers implicitly read by this instr
const unsigned *ImplicitDefs; // Registers implicitly defined by this instr const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered" const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands
/// getOperandConstraint - Returns the value of the specific constraint if /// getOperandConstraint - Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set. /// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum, int getOperandConstraint(unsigned OpNum,
TOI::OperandConstraint Constraint) const { MCOI::OperandConstraint Constraint) const {
if (OpNum < NumOperands && if (OpNum < NumOperands &&
(OpInfo[OpNum].Constraints & (1 << Constraint))) { (OpInfo[OpNum].Constraints & (1 << Constraint))) {
unsigned Pos = 16 + Constraint * 4; unsigned Pos = 16 + Constraint * 4;
@ -154,12 +154,6 @@ public:
return -1; return -1;
} }
/// getRegClass - Returns the register class constraint for OpNum, or NULL.
const TargetRegisterClass *getRegClass(unsigned OpNum,
const TargetRegisterInfo *TRI) const {
return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0;
}
/// getOpcode - Return the opcode number for this descriptor. /// getOpcode - Return the opcode number for this descriptor.
unsigned getOpcode() const { unsigned getOpcode() const {
return Opcode; return Opcode;
@ -193,13 +187,13 @@ public:
/// operands but before the implicit definitions and uses (if any are /// operands but before the implicit definitions and uses (if any are
/// present). /// present).
bool isVariadic() const { bool isVariadic() const {
return Flags & (1 << TID::Variadic); return Flags & (1 << MCID::Variadic);
} }
/// hasOptionalDef - Set if this instruction has an optional definition, e.g. /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
/// ARM instructions which can set condition code if 's' bit is set. /// ARM instructions which can set condition code if 's' bit is set.
bool hasOptionalDef() const { bool hasOptionalDef() const {
return Flags & (1 << TID::HasOptionalDef); return Flags & (1 << MCID::HasOptionalDef);
} }
/// getImplicitUses - Return a list of registers that are potentially /// getImplicitUses - Return a list of registers that are potentially
@ -214,7 +208,7 @@ public:
const unsigned *getImplicitUses() const { const unsigned *getImplicitUses() const {
return ImplicitUses; return ImplicitUses;
} }
/// getNumImplicitUses - Return the number of implicit uses this instruction /// getNumImplicitUses - Return the number of implicit uses this instruction
/// has. /// has.
unsigned getNumImplicitUses() const { unsigned getNumImplicitUses() const {
@ -223,8 +217,7 @@ public:
for (; ImplicitUses[i]; ++i) /*empty*/; for (; ImplicitUses[i]; ++i) /*empty*/;
return i; return i;
} }
/// getImplicitDefs - Return a list of registers that are potentially /// getImplicitDefs - Return a list of registers that are potentially
/// written by any instance of this machine instruction. For example, on X86, /// written by any instance of this machine instruction. For example, on X86,
/// many instructions implicitly set the flags register. In this case, they /// many instructions implicitly set the flags register. In this case, they
@ -266,17 +259,6 @@ public:
return false; return false;
} }
/// getRegClassBarriers - Return a list of register classes that are
/// completely clobbered by this machine instruction. For example, on X86
/// the call instructions will completely clobber all the registers in the
/// fp stack and XMM classes.
///
/// This method returns null if the instruction doesn't completely clobber
/// any register class.
const TargetRegisterClass **getRegClassBarriers() const {
return RCBarriers;
}
/// getSchedClass - Return the scheduling class for this instruction. The /// getSchedClass - Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This /// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the /// returns zero if there is no known scheduling information for the
@ -286,19 +268,25 @@ public:
return SchedClass; return SchedClass;
} }
/// getSize - Return the number of bytes in the encoding of this instruction,
/// or zero if the encoding size cannot be known from the opcode.
unsigned getSize() const {
return Size;
}
bool isReturn() const { bool isReturn() const {
return Flags & (1 << TID::Return); return Flags & (1 << MCID::Return);
} }
bool isCall() const { bool isCall() const {
return Flags & (1 << TID::Call); return Flags & (1 << MCID::Call);
} }
/// isBarrier - Returns true if the specified instruction stops control flow /// isBarrier - Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include /// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions. /// unconditional branches and return instructions.
bool isBarrier() const { bool isBarrier() const {
return Flags & (1 << TID::Barrier); return Flags & (1 << MCID::Barrier);
} }
/// isTerminator - Returns true if this instruction part of the terminator for /// isTerminator - Returns true if this instruction part of the terminator for
@ -308,7 +296,7 @@ public:
/// Various passes use this to insert code into the bottom of a basic block, /// Various passes use this to insert code into the bottom of a basic block,
/// but before control flow occurs. /// but before control flow occurs.
bool isTerminator() const { bool isTerminator() const {
return Flags & (1 << TID::Terminator); return Flags & (1 << MCID::Terminator);
} }
/// isBranch - Returns true if this is a conditional, unconditional, or /// isBranch - Returns true if this is a conditional, unconditional, or
@ -316,13 +304,13 @@ public:
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
/// get more information. /// get more information.
bool isBranch() const { bool isBranch() const {
return Flags & (1 << TID::Branch); return Flags & (1 << MCID::Branch);
} }
/// isIndirectBranch - Return true if this is an indirect branch, such as a /// isIndirectBranch - Return true if this is an indirect branch, such as a
/// branch through a register. /// branch through a register.
bool isIndirectBranch() const { bool isIndirectBranch() const {
return Flags & (1 << TID::IndirectBranch); return Flags & (1 << MCID::IndirectBranch);
} }
/// isConditionalBranch - Return true if this is a branch which may fall /// isConditionalBranch - Return true if this is a branch which may fall
@ -346,37 +334,37 @@ public:
/// values. There are various methods in TargetInstrInfo that can be used to /// values. There are various methods in TargetInstrInfo that can be used to
/// control and modify the predicate in this instruction. /// control and modify the predicate in this instruction.
bool isPredicable() const { bool isPredicable() const {
return Flags & (1 << TID::Predicable); return Flags & (1 << MCID::Predicable);
} }
/// isCompare - Return true if this instruction is a comparison. /// isCompare - Return true if this instruction is a comparison.
bool isCompare() const { bool isCompare() const {
return Flags & (1 << TID::Compare); return Flags & (1 << MCID::Compare);
} }
/// isMoveImmediate - Return true if this instruction is a move immediate /// isMoveImmediate - Return true if this instruction is a move immediate
/// (including conditional moves) instruction. /// (including conditional moves) instruction.
bool isMoveImmediate() const { bool isMoveImmediate() const {
return Flags & (1 << TID::MoveImm); return Flags & (1 << MCID::MoveImm);
} }
/// isBitcast - Return true if this instruction is a bitcast instruction. /// isBitcast - Return true if this instruction is a bitcast instruction.
/// ///
bool isBitcast() const { bool isBitcast() const {
return Flags & (1 << TID::Bitcast); return Flags & (1 << MCID::Bitcast);
} }
/// isNotDuplicable - Return true if this instruction cannot be safely /// isNotDuplicable - Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached /// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors. /// to it, duplicating it would cause multiple definition errors.
bool isNotDuplicable() const { bool isNotDuplicable() const {
return Flags & (1 << TID::NotDuplicable); return Flags & (1 << MCID::NotDuplicable);
} }
/// hasDelaySlot - Returns true if the specified instruction has a delay slot /// hasDelaySlot - Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator. /// which must be filled by the code generator.
bool hasDelaySlot() const { bool hasDelaySlot() const {
return Flags & (1 << TID::DelaySlot); return Flags & (1 << MCID::DelaySlot);
} }
/// canFoldAsLoad - Return true for instructions that can be folded as /// canFoldAsLoad - Return true for instructions that can be folded as
@ -388,7 +376,7 @@ public:
/// This should only be set on instructions that return a value in their /// This should only be set on instructions that return a value in their
/// only virtual register definition. /// only virtual register definition.
bool canFoldAsLoad() const { bool canFoldAsLoad() const {
return Flags & (1 << TID::FoldableAsLoad); return Flags & (1 << MCID::FoldableAsLoad);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -399,7 +387,7 @@ public:
/// Instructions with this flag set are not necessarily simple load /// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example. /// instructions, they may load a value and modify it, for example.
bool mayLoad() const { bool mayLoad() const {
return Flags & (1 << TID::MayLoad); return Flags & (1 << MCID::MayLoad);
} }
@ -408,7 +396,7 @@ public:
/// instructions, they may store a modified value based on their operands, or /// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example. /// may not actually modify anything, for example.
bool mayStore() const { bool mayStore() const {
return Flags & (1 << TID::MayStore); return Flags & (1 << MCID::MayStore);
} }
/// hasUnmodeledSideEffects - Return true if this instruction has side /// hasUnmodeledSideEffects - Return true if this instruction has side
@ -425,7 +413,7 @@ public:
/// LLVM, etc. /// LLVM, etc.
/// ///
bool hasUnmodeledSideEffects() const { bool hasUnmodeledSideEffects() const {
return Flags & (1 << TID::UnmodeledSideEffects); return Flags & (1 << MCID::UnmodeledSideEffects);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -443,7 +431,7 @@ public:
/// Also note that some instructions require non-trivial modification to /// Also note that some instructions require non-trivial modification to
/// commute them. /// commute them.
bool isCommutable() const { bool isCommutable() const {
return Flags & (1 << TID::Commutable); return Flags & (1 << MCID::Commutable);
} }
/// isConvertibleTo3Addr - Return true if this is a 2-address instruction /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
@ -461,7 +449,7 @@ public:
/// instruction (e.g. shl reg, 4 on x86). /// instruction (e.g. shl reg, 4 on x86).
/// ///
bool isConvertibleTo3Addr() const { bool isConvertibleTo3Addr() const {
return Flags & (1 << TID::ConvertibleTo3Addr); return Flags & (1 << MCID::ConvertibleTo3Addr);
} }
/// usesCustomInsertionHook - Return true if this instruction requires /// usesCustomInsertionHook - Return true if this instruction requires
@ -473,7 +461,7 @@ public:
/// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
/// is used to insert this into the MachineBasicBlock. /// is used to insert this into the MachineBasicBlock.
bool usesCustomInsertionHook() const { bool usesCustomInsertionHook() const {
return Flags & (1 << TID::UsesCustomInserter); return Flags & (1 << MCID::UsesCustomInserter);
} }
/// isRematerializable - Returns true if this instruction is a candidate for /// isRematerializable - Returns true if this instruction is a candidate for
@ -481,7 +469,7 @@ public:
/// flag is set, the isReallyTriviallyReMaterializable() method is called to /// flag is set, the isReallyTriviallyReMaterializable() method is called to
/// verify the instruction is really rematable. /// verify the instruction is really rematable.
bool isRematerializable() const { bool isRematerializable() const {
return Flags & (1 << TID::Rematerializable); return Flags & (1 << MCID::Rematerializable);
} }
/// isAsCheapAsAMove - Returns true if this instruction has the same cost (or /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
@ -491,7 +479,7 @@ public:
/// more than moving the instruction into the appropriate register. Note, we /// more than moving the instruction into the appropriate register. Note, we
/// are not marking copies from and to the same register class with this flag. /// are not marking copies from and to the same register class with this flag.
bool isAsCheapAsAMove() const { bool isAsCheapAsAMove() const {
return Flags & (1 << TID::CheapAsAMove); return Flags & (1 << MCID::CheapAsAMove);
} }
/// hasExtraSrcRegAllocReq - Returns true if this instruction source operands /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
@ -501,7 +489,7 @@ public:
/// Post-register allocation passes should not attempt to change allocations /// Post-register allocation passes should not attempt to change allocations
/// for sources of instructions with this flag. /// for sources of instructions with this flag.
bool hasExtraSrcRegAllocReq() const { bool hasExtraSrcRegAllocReq() const {
return Flags & (1 << TID::ExtraSrcRegAllocReq); return Flags & (1 << MCID::ExtraSrcRegAllocReq);
} }
/// hasExtraDefRegAllocReq - Returns true if this instruction def operands /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
@ -511,7 +499,7 @@ public:
/// Post-register allocation passes should not attempt to change allocations /// Post-register allocation passes should not attempt to change allocations
/// for definitions of instructions with this flag. /// for definitions of instructions with this flag.
bool hasExtraDefRegAllocReq() const { bool hasExtraDefRegAllocReq() const {
return Flags & (1 << TID::ExtraDefRegAllocReq); return Flags & (1 << MCID::ExtraDefRegAllocReq);
} }
}; };

View File

@ -0,0 +1,51 @@
//===-- llvm/MC/MCInstrInfo.h - Target Instruction Info ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the target machine instruction set.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCINSTRINFO_H
#define LLVM_MC_MCINSTRINFO_H
#include "llvm/MC/MCInstrDesc.h"
#include <cassert>
namespace llvm {
//---------------------------------------------------------------------------
///
/// MCInstrInfo - Interface to description of machine instruction set
///
class MCInstrInfo {
const MCInstrDesc *Desc; // Raw array to allow static init'n
unsigned NumOpcodes; // Number of entries in the desc array
public:
/// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCInstrInfo(const MCInstrDesc *D, unsigned NO) {
Desc = D;
NumOpcodes = NO;
}
unsigned getNumOpcodes() const { return NumOpcodes; }
/// get - Return the machine instruction descriptor that corresponds to the
/// specified instruction opcode.
///
const MCInstrDesc &get(unsigned Opcode) const {
assert(Opcode < NumOpcodes && "Invalid opcode!");
return Desc[Opcode];
}
};
} // End llvm namespace
#endif

View File

@ -1,4 +1,4 @@
//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===// //===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,8 +13,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H #ifndef LLVM_MC_MCINSTRITINERARIES_H
#define LLVM_TARGET_TARGETINSTRITINERARIES_H #define LLVM_MC_MCINSTRITINERARIES_H
#include <algorithm> #include <algorithm>

View File

@ -10,11 +10,20 @@
#ifndef LLVM_MC_MCMACHOBJECTWRITER_H #ifndef LLVM_MC_MCMACHOBJECTWRITER_H
#define LLVM_MC_MCMACHOBJECTWRITER_H #define LLVM_MC_MCMACHOBJECTWRITER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCObjectWriter.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm { namespace llvm {
class MCSectionData;
class MachObjectWriter;
class MCMachObjectTargetWriter { class MCMachObjectTargetWriter {
const unsigned Is64Bit : 1; const unsigned Is64Bit : 1;
const uint32_t CPUType; const uint32_t CPUType;
@ -48,8 +57,191 @@ public:
} }
/// @} /// @}
/// @name API
/// @{
virtual void RecordRelocation(MachObjectWriter *Writer,
const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) = 0;
/// @}
}; };
class MachObjectWriter : public MCObjectWriter {
/// MachSymbolData - Helper struct for containing some precomputed information
/// on symbols.
struct MachSymbolData {
MCSymbolData *SymbolData;
uint64_t StringIndex;
uint8_t SectionIndex;
// Support lexicographic sorting.
bool operator<(const MachSymbolData &RHS) const;
};
/// The target specific Mach-O writer instance.
llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
/// @name Relocation Data
/// @{
llvm::DenseMap<const MCSectionData*,
std::vector<object::macho::RelocationEntry> > Relocations;
llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
/// @}
/// @name Symbol Table Data
/// @{
SmallString<256> StringTable;
std::vector<MachSymbolData> LocalSymbolData;
std::vector<MachSymbolData> ExternalSymbolData;
std::vector<MachSymbolData> UndefinedSymbolData;
/// @}
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
bool _IsLittleEndian)
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
}
/// @name Utility Methods
/// @{
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
SectionAddrMap SectionAddress;
SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
uint64_t getSectionAddress(const MCSectionData* SD) const {
return SectionAddress.lookup(SD);
}
uint64_t getSymbolAddress(const MCSymbolData* SD,
const MCAsmLayout &Layout) const;
uint64_t getFragmentAddress(const MCFragment *Fragment,
const MCAsmLayout &Layout) const;
uint64_t getPaddingSize(const MCSectionData *SD,
const MCAsmLayout &Layout) const;
bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
/// @}
/// @name Target Writer Proxy Accessors
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool isARM() const {
uint32_t CPUType = TargetObjectWriter->getCPUType() &
~object::mach::CTFM_ArchMask;
return CPUType == object::mach::CTM_ARM;
}
/// @}
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols);
/// WriteSegmentLoadCommand - Write a segment load command.
///
/// \arg NumSections - The number of sections in this segment.
/// \arg SectionDataSize - The total size of the sections.
void WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize);
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations);
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
uint32_t StringTableOffset,
uint32_t StringTableSize);
void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
uint32_t NumLocalSymbols,
uint32_t FirstExternalSymbol,
uint32_t NumExternalSymbols,
uint32_t FirstUndefinedSymbol,
uint32_t NumUndefinedSymbols,
uint32_t IndirectSymbolOffset,
uint32_t NumIndirectSymbols);
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
// exactly what the encoder wanted. This will catch several classes of
// problems:
//
// - Relocation entry bugs, the two algorithms are unlikely to have the same
// exact bug.
//
// - Relaxation issues, where we forget to relax something.
//
// - Input errors, where something cannot be correctly encoded. 'as' allows
// these through in many cases.
void addRelocation(const MCSectionData *SD,
object::macho::RelocationEntry &MRE) {
Relocations[SD].push_back(MRE);
}
void RecordScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue);
void RecordTLVPRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue);
void BindIndirectSymbols(MCAssembler &Asm);
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
/// \param StringIndexMap [out] - Map from symbol names to offsets in the
/// string table.
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
std::vector<MachSymbolData> &UndefinedSymbolData);
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const;
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
/// \brief Construct a new Mach-O writer instance. /// \brief Construct a new Mach-O writer instance.
/// ///
/// This routine takes ownership of the target writer subclass. /// This routine takes ownership of the target writer subclass.

View File

@ -73,7 +73,8 @@ public:
virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel, const MCSymbol *LastLabel,
const MCSymbol *Label); const MCSymbol *Label,
unsigned PointerSize);
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label); const MCSymbol *Label);
virtual void Finish(); virtual void Finish();

View File

@ -28,10 +28,20 @@ public:
/// getEndLoc - Get the location of the last token of this operand. /// getEndLoc - Get the location of the last token of this operand.
virtual SMLoc getEndLoc() const = 0; virtual SMLoc getEndLoc() const = 0;
/// dump - Print a debug representation of the operand to the given stream. /// print - Print a debug representation of the operand to the given stream.
virtual void dump(raw_ostream &OS) const = 0; virtual void print(raw_ostream &OS) const = 0;
/// dump - Print to the debug stream.
virtual void dump() const;
}; };
//===----------------------------------------------------------------------===//
// Debugging Support
inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
MO.print(OS);
return OS;
}
} // end namespace llvm. } // end namespace llvm.
#endif #endif

View File

@ -0,0 +1,129 @@
//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes an abstract interface used to get information about a
// target machines register file. This information is used for a variety of
// purposed, especially register allocation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCREGISTERINFO_H
#define LLVM_MC_MCREGISTERINFO_H
#include <cassert>
namespace llvm {
/// MCRegisterDesc - This record contains all of the information known about
/// a particular register. The Overlaps field contains a pointer to a zero
/// terminated array of registers that this register aliases, starting with
/// itself. This is needed for architectures like X86 which have AL alias AX
/// alias EAX. The SubRegs field is a zero terminated array of registers that
/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
/// AX. The SuperRegs field is a zero terminated array of registers that are
/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
/// of AX.
///
struct MCRegisterDesc {
const char *Name; // Printable name for the reg (for debugging)
const unsigned *Overlaps; // Overlapping registers, described above
const unsigned *SubRegs; // Sub-register set, described above
const unsigned *SuperRegs; // Super-register set, described above
};
/// MCRegisterInfo base class - We assume that the target defines a static
/// array of MCRegisterDesc objects that represent all of the machine
/// registers that the target has. As such, we simply have to track a pointer
/// to this array so that we can turn register number into a register
/// descriptor.
///
/// Note this class is designed to be a base class of TargetRegisterInfo, which
/// is the interface used by codegen. However, specific targets *should never*
/// specialize this class. MCRegisterInfo should only contain getters to access
/// TableGen generated physical register data. It must not be extended with
/// virtual methods.
///
class MCRegisterInfo {
private:
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
public:
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR) {
Desc = D;
NumRegs = NR;
}
const MCRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to access record for invalid register number!");
return Desc[RegNo];
}
/// Provide a get method, equivalent to [], but more useful if we have a
/// pointer to this object.
///
const MCRegisterDesc &get(unsigned RegNo) const {
return operator[](RegNo);
}
/// getAliasSet - Return the set of registers aliased by the specified
/// register, or a null list of there are none. The list returned is zero
/// terminated.
///
const unsigned *getAliasSet(unsigned RegNo) const {
// The Overlaps set always begins with Reg itself.
return get(RegNo).Overlaps + 1;
}
/// getOverlaps - Return a list of registers that overlap Reg, including
/// itself. This is the same as the alias set except Reg is included in the
/// list.
/// These are exactly the registers in { x | regsOverlap(x, Reg) }.
///
const unsigned *getOverlaps(unsigned RegNo) const {
return get(RegNo).Overlaps;
}
/// getSubRegisters - Return the list of registers that are sub-registers of
/// the specified register, or a null list of there are none. The list
/// returned is zero terminated and sorted according to super-sub register
/// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
///
const unsigned *getSubRegisters(unsigned RegNo) const {
return get(RegNo).SubRegs;
}
/// getSuperRegisters - Return the list of registers that are super-registers
/// of the specified register, or a null list of there are none. The list
/// returned is zero terminated and sorted according to super-sub register
/// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
///
const unsigned *getSuperRegisters(unsigned RegNo) const {
return get(RegNo).SuperRegs;
}
/// getName - Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
return get(RegNo).Name;
}
/// getNumRegs - Return the number of registers this target has (useful for
/// sizing arrays holding per register information)
unsigned getNumRegs() const {
return NumRegs;
}
};
} // End llvm namespace
#endif

View File

@ -460,7 +460,8 @@ namespace llvm {
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel, const MCSymbol *LastLabel,
const MCSymbol *Label) = 0; const MCSymbol *Label,
unsigned PointerSize) = 0;
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label) { const MCSymbol *Label) {
@ -547,6 +548,9 @@ namespace llvm {
/// ///
/// \param ShowInst - Whether to show the MCInst representation inline with /// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly. /// the assembly.
///
/// \param DecodeLSDA - If true, emit comments that translates the LSDA into a
/// human readable format. Only usable with CFI.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool isVerboseAsm,
bool useLoc, bool useLoc,

View File

@ -0,0 +1,79 @@
//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the subtarget options of a Target machine.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSUBTARGET_H
#define LLVM_MC_MCSUBTARGET_H
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/MC/MCInstrItineraries.h"
#include <string>
namespace llvm {
class StringRef;
//===----------------------------------------------------------------------===//
///
/// MCSubtargetInfo - Generic base class for all target subtargets.
///
class MCSubtargetInfo {
std::string TargetTriple; // Target triple
const SubtargetFeatureKV *ProcFeatures; // Processor feature list
const SubtargetFeatureKV *ProcDesc; // Processor descriptions
const SubtargetInfoKV *ProcItins; // Scheduling itineraries
const InstrStage *Stages; // Instruction stages
const unsigned *OperandCycles; // Operand cycles
const unsigned *ForwardingPathes; // Forwarding pathes
unsigned NumFeatures; // Number of processor features
unsigned NumProcs; // Number of processors
uint64_t FeatureBits; // Feature bits for current CPU + FS
public:
void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
const SubtargetInfoKV *PI, const InstrStage *IS,
const unsigned *OC, const unsigned *FP,
unsigned NF, unsigned NP);
/// getTargetTriple - Return the target triple string.
StringRef getTargetTriple() const {
return TargetTriple;
}
/// getFeatureBits - Return the feature bits.
///
uint64_t getFeatureBits() const {
return FeatureBits;
}
/// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
/// feature string), recompute and return feature bits.
uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version does not change the implied bits.
uint64_t ToggleFeature(uint64_t FB);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version will also change all implied bits.
uint64_t ToggleFeature(StringRef FS);
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
///
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
};
} // End llvm namespace
#endif

View File

@ -1,4 +1,4 @@
//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===// //===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -15,17 +15,16 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_SUBTARGETFEATURE_H #ifndef LLVM_MC_SUBTARGETFEATURE_H
#define LLVM_TARGET_SUBTARGETFEATURE_H #define LLVM_MC_SUBTARGETFEATURE_H
#include <string>
#include <vector> #include <vector>
#include <cstring>
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm { namespace llvm {
class raw_ostream; class raw_ostream;
class StringRef;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// ///
@ -75,32 +74,30 @@ struct SubtargetInfoKV {
class SubtargetFeatures { class SubtargetFeatures {
std::vector<std::string> Features; // Subtarget features as a vector std::vector<std::string> Features; // Subtarget features as a vector
public: public:
explicit SubtargetFeatures(const std::string &Initial = std::string()); explicit SubtargetFeatures(const StringRef Initial = "");
/// Features string accessors. /// Features string accessors.
std::string getString() const; std::string getString() const;
void setString(const std::string &Initial);
/// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
void setCPU(const std::string &String);
/// Setting CPU string only if no string is set.
void setCPUIfNone(const std::string &String);
/// Returns current CPU string.
const std::string & getCPU() const;
/// Adding Features. /// Adding Features.
void AddFeature(const std::string &String, bool IsEnabled = true); void AddFeature(const StringRef String, bool IsEnabled = true);
/// Get feature bits. /// ToggleFeature - Toggle a feature and returns the newly updated feature
uint64_t getBits(const SubtargetFeatureKV *CPUTable, /// bits.
size_t CPUTableSize, uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
const SubtargetFeatureKV *FeatureTable, const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize); size_t FeatureTableSize);
/// Get feature bits of a CPU.
uint64_t getFeatureBits(const StringRef CPU,
const SubtargetFeatureKV *CPUTable,
size_t CPUTableSize,
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
/// Get info pointer /// Get scheduling itinerary of a CPU.
void *getInfo(const SubtargetInfoKV *Table, size_t TableSize); void *getItinerary(const StringRef CPU,
const SubtargetInfoKV *Table, size_t TableSize);
/// Print feature string. /// Print feature string.
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
@ -110,8 +107,7 @@ public:
/// Retrieve a formatted string of the default features for the specified /// Retrieve a formatted string of the default features for the specified
/// target triple. /// target triple.
void getDefaultSubtargetFeatures(const std::string &CPU, void getDefaultSubtargetFeatures(const Triple& Triple);
const Triple& Triple);
}; };
} // End namespace llvm } // End namespace llvm

View File

@ -28,6 +28,10 @@ namespace llvm {
class FunctionType; class FunctionType;
class GVMaterializer; class GVMaterializer;
class LLVMContext; class LLVMContext;
class StructType;
template<typename T> struct DenseMapInfo;
template<typename KeyT, typename ValueT,
typename KeyInfoT, typename ValueInfoT> class DenseMap;
template<> struct ilist_traits<Function> template<> struct ilist_traits<Function>
: public SymbolTableListTraits<Function, Module> { : public SymbolTableListTraits<Function, Module> {
@ -145,7 +149,6 @@ private:
NamedMDListType NamedMDList; ///< The named metadata in the module NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope. std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values ValueSymbolTable *ValSymTab; ///< Symbol table for values
TypeSymbolTable *TypeSymTab; ///< Symbol table for types
OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues
std::string ModuleID; ///< Human readable identifier for the module std::string ModuleID; ///< Human readable identifier for the module
std::string TargetTriple; ///< Platform target triple Module compiled on std::string TargetTriple; ///< Platform target triple Module compiled on
@ -231,7 +234,7 @@ public:
/// @name Generic Value Accessors /// @name Generic Value Accessors
/// @{ /// @{
/// getNamedValue - Return the first global value in the module with /// getNamedValue - Return the global value in the module with
/// the specified name, of arbitrary type. This method returns null /// the specified name, of arbitrary type. This method returns null
/// if a global with the specified name is not found. /// if a global with the specified name is not found.
GlobalValue *getNamedValue(StringRef Name) const; GlobalValue *getNamedValue(StringRef Name) const;
@ -244,6 +247,18 @@ public:
/// custom metadata IDs registered in this LLVMContext. /// custom metadata IDs registered in this LLVMContext.
void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*>,
DenseMapInfo<unsigned> > NumeredTypesMapTy;
/// findUsedStructTypes - Walk the entire module and find all of the
/// struct types that are in use, returning them in a vector.
void findUsedStructTypes(std::vector<StructType*> &StructTypes) const;
/// getTypeByName - Return the type with the specified name, or null if there
/// is none by that name.
StructType *getTypeByName(StringRef Name) const;
/// @} /// @}
/// @name Function Accessors /// @name Function Accessors
/// @{ /// @{
@ -296,7 +311,7 @@ public:
GlobalVariable *getGlobalVariable(StringRef Name, GlobalVariable *getGlobalVariable(StringRef Name,
bool AllowInternal = false) const; bool AllowInternal = false) const;
/// getNamedGlobal - Return the first global variable in the module with the /// getNamedGlobal - Return the global variable in the module with the
/// specified name, of arbitrary type. This method returns null if a global /// specified name, of arbitrary type. This method returns null if a global
/// with the specified name is not found. /// with the specified name is not found.
GlobalVariable *getNamedGlobal(StringRef Name) const { GlobalVariable *getNamedGlobal(StringRef Name) const {
@ -316,7 +331,7 @@ public:
/// @name Global Alias Accessors /// @name Global Alias Accessors
/// @{ /// @{
/// getNamedAlias - Return the first global alias in the module with the /// getNamedAlias - Return the global alias in the module with the
/// specified name, of arbitrary type. This method returns null if a global /// specified name, of arbitrary type. This method returns null if a global
/// with the specified name is not found. /// with the specified name is not found.
GlobalAlias *getNamedAlias(StringRef Name) const; GlobalAlias *getNamedAlias(StringRef Name) const;
@ -325,12 +340,12 @@ public:
/// @name Named Metadata Accessors /// @name Named Metadata Accessors
/// @{ /// @{
/// getNamedMetadata - Return the first NamedMDNode in the module with the /// getNamedMetadata - Return the NamedMDNode in the module with the
/// specified name. This method returns null if a NamedMDNode with the /// specified name. This method returns null if a NamedMDNode with the
/// specified name is not found. /// specified name is not found.
NamedMDNode *getNamedMetadata(const Twine &Name) const; NamedMDNode *getNamedMetadata(const Twine &Name) const;
/// getOrInsertNamedMetadata - Return the first named MDNode in the module /// getOrInsertNamedMetadata - Return the named MDNode in the module
/// with the specified name. This method returns a new NamedMDNode if a /// with the specified name. This method returns a new NamedMDNode if a
/// NamedMDNode with the specified name is not found. /// NamedMDNode with the specified name is not found.
NamedMDNode *getOrInsertNamedMetadata(StringRef Name); NamedMDNode *getOrInsertNamedMetadata(StringRef Name);
@ -339,23 +354,6 @@ public:
/// and delete it. /// and delete it.
void eraseNamedMetadata(NamedMDNode *NMD); void eraseNamedMetadata(NamedMDNode *NMD);
/// @}
/// @name Type Accessors
/// @{
/// addTypeName - Insert an entry in the symbol table mapping Str to Type. If
/// there is already an entry for this name, true is returned and the symbol
/// table is not modified.
bool addTypeName(StringRef Name, const Type *Ty);
/// getTypeName - If there is at least one entry in the symbol table for the
/// specified type, return it.
std::string getTypeName(const Type *Ty) const;
/// getTypeByName - Return the type with the specified name in this module, or
/// null if there is none by that name.
const Type *getTypeByName(StringRef Name) const;
/// @} /// @}
/// @name Materialization /// @name Materialization
/// @{ /// @{
@ -429,41 +427,26 @@ public:
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; } const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers. /// Get the Module's symbol table of global variable and function identifiers.
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; } ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
/// Get the symbol table of types
const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; }
/// Get the Module's symbol table of types
TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; }
/// @} /// @}
/// @name Global Variable Iteration /// @name Global Variable Iteration
/// @{ /// @{
/// Get an iterator to the first global variable
global_iterator global_begin() { return GlobalList.begin(); } global_iterator global_begin() { return GlobalList.begin(); }
/// Get a constant iterator to the first global variable
const_global_iterator global_begin() const { return GlobalList.begin(); } const_global_iterator global_begin() const { return GlobalList.begin(); }
/// Get an iterator to the last global variable
global_iterator global_end () { return GlobalList.end(); } global_iterator global_end () { return GlobalList.end(); }
/// Get a constant iterator to the last global variable
const_global_iterator global_end () const { return GlobalList.end(); } const_global_iterator global_end () const { return GlobalList.end(); }
/// Determine if the list of globals is empty.
bool global_empty() const { return GlobalList.empty(); } bool global_empty() const { return GlobalList.empty(); }
/// @} /// @}
/// @name Function Iteration /// @name Function Iteration
/// @{ /// @{
/// Get an iterator to the first function.
iterator begin() { return FunctionList.begin(); } iterator begin() { return FunctionList.begin(); }
/// Get a constant iterator to the first function.
const_iterator begin() const { return FunctionList.begin(); } const_iterator begin() const { return FunctionList.begin(); }
/// Get an iterator to the last function.
iterator end () { return FunctionList.end(); } iterator end () { return FunctionList.end(); }
/// Get a constant iterator to the last function.
const_iterator end () const { return FunctionList.end(); } const_iterator end () const { return FunctionList.end(); }
/// Determine how many functions are in the Module's list of functions.
size_t size() const { return FunctionList.size(); } size_t size() const { return FunctionList.size(); }
/// Determine if the list of functions is empty.
bool empty() const { return FunctionList.empty(); } bool empty() const { return FunctionList.empty(); }
/// @} /// @}
@ -487,17 +470,11 @@ public:
/// @name Alias Iteration /// @name Alias Iteration
/// @{ /// @{
/// Get an iterator to the first alias.
alias_iterator alias_begin() { return AliasList.begin(); } alias_iterator alias_begin() { return AliasList.begin(); }
/// Get a constant iterator to the first alias.
const_alias_iterator alias_begin() const { return AliasList.begin(); } const_alias_iterator alias_begin() const { return AliasList.begin(); }
/// Get an iterator to the last alias.
alias_iterator alias_end () { return AliasList.end(); } alias_iterator alias_end () { return AliasList.end(); }
/// Get a constant iterator to the last alias.
const_alias_iterator alias_end () const { return AliasList.end(); } const_alias_iterator alias_end () const { return AliasList.end(); }
/// Determine how many aliases are in the Module's list of aliases.
size_t alias_size () const { return AliasList.size(); } size_t alias_size () const { return AliasList.size(); }
/// Determine if the list of aliases is empty.
bool alias_empty() const { return AliasList.empty(); } bool alias_empty() const { return AliasList.empty(); }
@ -505,24 +482,17 @@ public:
/// @name Named Metadata Iteration /// @name Named Metadata Iteration
/// @{ /// @{
/// Get an iterator to the first named metadata.
named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); } named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); }
/// Get a constant iterator to the first named metadata.
const_named_metadata_iterator named_metadata_begin() const { const_named_metadata_iterator named_metadata_begin() const {
return NamedMDList.begin(); return NamedMDList.begin();
} }
/// Get an iterator to the last named metadata.
named_metadata_iterator named_metadata_end() { return NamedMDList.end(); } named_metadata_iterator named_metadata_end() { return NamedMDList.end(); }
/// Get a constant iterator to the last named metadata.
const_named_metadata_iterator named_metadata_end() const { const_named_metadata_iterator named_metadata_end() const {
return NamedMDList.end(); return NamedMDList.end();
} }
/// Determine how many NamedMDNodes are in the Module's list of named
/// metadata.
size_t named_metadata_size() const { return NamedMDList.size(); } size_t named_metadata_size() const { return NamedMDList.size(); }
/// Determine if the list of named metadata is empty.
bool named_metadata_empty() const { return NamedMDList.empty(); } bool named_metadata_empty() const { return NamedMDList.empty(); }
@ -530,11 +500,13 @@ public:
/// @name Utility functions for printing and dumping Module objects /// @name Utility functions for printing and dumping Module objects
/// @{ /// @{
/// Print the module to an output stream with AssemblyAnnotationWriter. /// Print the module to an output stream with an optional
/// AssemblyAnnotationWriter.
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const; void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const;
/// Dump the module to stderr (for debugging). /// Dump the module to stderr (for debugging).
void dump() const; void dump() const;
/// This function causes all the subinstructions to "let go" of all references /// This function causes all the subinstructions to "let go" of all references
/// that they are maintaining. This allows one to 'delete' a whole class at /// that they are maintaining. This allows one to 'delete' a whole class at
/// a time, even though there may be circular references... first all /// a time, even though there may be circular references... first all

View File

@ -0,0 +1,67 @@
//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the Binary class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_BINARY_H
#define LLVM_OBJECT_BINARY_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Object/Error.h"
namespace llvm {
class MemoryBuffer;
class StringRef;
namespace object {
class Binary {
private:
Binary(); // = delete
Binary(const Binary &other); // = delete
unsigned int TypeID;
protected:
MemoryBuffer *Data;
Binary(unsigned int Type, MemoryBuffer *Source);
enum {
isArchive,
// Object and children.
isObject,
isCOFF,
isELF,
isMachO,
lastObject
};
public:
virtual ~Binary();
StringRef getData() const;
StringRef getFileName() const;
// Cast methods.
unsigned int getType() const { return TypeID; }
static inline bool classof(const Binary *v) { return true; }
};
error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);
error_code createBinary(StringRef Path, OwningPtr<Binary> &Result);
}
}
#endif

View File

@ -0,0 +1,117 @@
//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the COFFObjectFile class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_COFF_H
#define LLVM_OBJECT_COFF_H
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
namespace llvm {
namespace object {
struct coff_file_header {
support::ulittle16_t Machine;
support::ulittle16_t NumberOfSections;
support::ulittle32_t TimeDateStamp;
support::ulittle32_t PointerToSymbolTable;
support::ulittle32_t NumberOfSymbols;
support::ulittle16_t SizeOfOptionalHeader;
support::ulittle16_t Characteristics;
};
struct coff_symbol {
struct StringTableOffset {
support::ulittle32_t Zeroes;
support::ulittle32_t Offset;
};
union {
char ShortName[8];
StringTableOffset Offset;
} Name;
support::ulittle32_t Value;
support::little16_t SectionNumber;
struct {
support::ulittle8_t BaseType;
support::ulittle8_t ComplexType;
} Type;
support::ulittle8_t StorageClass;
support::ulittle8_t NumberOfAuxSymbols;
};
struct coff_section {
char Name[8];
support::ulittle32_t VirtualSize;
support::ulittle32_t VirtualAddress;
support::ulittle32_t SizeOfRawData;
support::ulittle32_t PointerToRawData;
support::ulittle32_t PointerToRelocations;
support::ulittle32_t PointerToLinenumbers;
support::ulittle16_t NumberOfRelocations;
support::ulittle16_t NumberOfLinenumbers;
support::ulittle32_t Characteristics;
};
class COFFObjectFile : public ObjectFile {
private:
const coff_file_header *Header;
const coff_section *SectionTable;
const coff_symbol *SymbolTable;
const char *StringTable;
uint32_t StringTableSize;
error_code getSection(int32_t index,
const coff_section *&Res) const;
error_code getString(uint32_t offset, StringRef &Res) const;
const coff_symbol *toSymb(DataRefImpl Symb) const;
const coff_section *toSec(DataRefImpl Sec) const;
protected:
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
bool &Result) const;
public:
COFFObjectFile(MemoryBuffer *Object, error_code &ec);
virtual symbol_iterator begin_symbols() const;
virtual symbol_iterator end_symbols() const;
virtual section_iterator begin_sections() const;
virtual section_iterator end_sections() const;
virtual uint8_t getBytesInAddress() const;
virtual StringRef getFileFormatName() const;
virtual unsigned getArch() const;
};
}
}
#endif

View File

@ -0,0 +1,50 @@
//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This declares a new error_category for the Object library.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_ERROR_H
#define LLVM_OBJECT_ERROR_H
#include "llvm/Support/system_error.h"
namespace llvm {
namespace object {
const error_category &object_category();
struct object_error {
enum _ {
success = 0,
invalid_file_type,
parse_failed,
unexpected_eof
};
_ v_;
object_error(_ v) : v_(v) {}
explicit object_error(int v) : v_(_(v)) {}
operator int() const {return v_;}
};
inline error_code make_error_code(object_error e) {
return error_code(static_cast<int>(e), object_category());
}
} // end namespace object.
template <> struct is_error_code_enum<object::object_error> : true_type { };
template <> struct is_error_code_enum<object::object_error::_> : true_type { };
} // end namespace llvm.
#endif

View File

@ -14,15 +14,14 @@
#ifndef LLVM_OBJECT_OBJECT_FILE_H #ifndef LLVM_OBJECT_OBJECT_FILE_H
#define LLVM_OBJECT_OBJECT_FILE_H #define LLVM_OBJECT_OBJECT_FILE_H
#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstring> #include <cstring>
namespace llvm { namespace llvm {
class MemoryBuffer;
class StringRef;
namespace object { namespace object {
class ObjectFile; class ObjectFile;
@ -31,7 +30,7 @@ union DataRefImpl {
struct { struct {
uint32_t a, b; uint32_t a, b;
} d; } d;
intptr_t p; uintptr_t p;
}; };
static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
@ -40,52 +39,80 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
} }
class RelocationRef {
DataRefImpl RelocationPimpl;
const ObjectFile *OwningObject;
public:
RelocationRef() : OwningObject(NULL) {
std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl));
}
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
bool operator==(const RelocationRef &Other) const;
error_code getNext(RelocationRef &Result);
};
/// SymbolRef - This is a value type class that represents a single symbol in /// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file. /// the list of symbols in the object file.
class SymbolRef { class SymbolRef {
friend class SectionRef;
DataRefImpl SymbolPimpl; DataRefImpl SymbolPimpl;
const ObjectFile *OwningObject; const ObjectFile *OwningObject;
public: public:
SymbolRef() : OwningObject(NULL) {
std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl));
}
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
bool operator==(const SymbolRef &Other) const; bool operator==(const SymbolRef &Other) const;
SymbolRef getNext() const; error_code getNext(SymbolRef &Result) const;
StringRef getName() const; error_code getName(StringRef &Result) const;
uint64_t getAddress() const; error_code getAddress(uint64_t &Result) const;
uint64_t getSize() const; error_code getSize(uint64_t &Result) const;
/// Returns the ascii char that should be displayed in a symbol table dump via /// Returns the ascii char that should be displayed in a symbol table dump via
/// nm for this symbol. /// nm for this symbol.
char getNMTypeChar() const; error_code getNMTypeChar(char &Result) const;
/// Returns true for symbols that are internal to the object file format such /// Returns true for symbols that are internal to the object file format such
/// as section symbols. /// as section symbols.
bool isInternal() const; error_code isInternal(bool &Result) const;
}; };
/// SectionRef - This is a value type class that represents a single section in /// SectionRef - This is a value type class that represents a single section in
/// the list of sections in the object file. /// the list of sections in the object file.
class SectionRef { class SectionRef {
friend class SymbolRef;
DataRefImpl SectionPimpl; DataRefImpl SectionPimpl;
const ObjectFile *OwningObject; const ObjectFile *OwningObject;
public: public:
SectionRef() : OwningObject(NULL) {
std::memset(&SectionPimpl, 0, sizeof(SectionPimpl));
}
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const; bool operator==(const SectionRef &Other) const;
SectionRef getNext() const; error_code getNext(SectionRef &Result) const;
StringRef getName() const; error_code getName(StringRef &Result) const;
uint64_t getAddress() const; error_code getAddress(uint64_t &Result) const;
uint64_t getSize() const; error_code getSize(uint64_t &Result) const;
StringRef getContents() const; error_code getContents(StringRef &Result) const;
// FIXME: Move to the normalization layer when it's created. // FIXME: Move to the normalization layer when it's created.
bool isText() const; error_code isText(bool &Result) const;
error_code containsSymbol(SymbolRef S, bool &Result) const;
}; };
const uint64_t UnknownAddressOrSize = ~0ULL; const uint64_t UnknownAddressOrSize = ~0ULL;
@ -93,38 +120,44 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
/// ObjectFile - This class is the base class for all object file types. /// ObjectFile - This class is the base class for all object file types.
/// Concrete instances of this object are created by createObjectFile, which /// Concrete instances of this object are created by createObjectFile, which
/// figure out which type to create. /// figure out which type to create.
class ObjectFile { class ObjectFile : public Binary {
private: private:
ObjectFile(); // = delete ObjectFile(); // = delete
ObjectFile(const ObjectFile &other); // = delete ObjectFile(const ObjectFile &other); // = delete
protected: protected:
MemoryBuffer *MapFile; ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
const uint8_t *base;
ObjectFile(MemoryBuffer *Object); const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
}
// These functions are for SymbolRef to call internally. The main goal of // These functions are for SymbolRef to call internally. The main goal of
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
// entry in the memory mapped object file. SymbolPimpl cannot contain any // entry in the memory mapped object file. SymbolPimpl cannot contain any
// virtual functions because then it could not point into the memory mapped // virtual functions because then it could not point into the memory mapped
// file. // file.
//
// Implementations assume that the DataRefImpl is valid and has not been
// modified externally. It's UB otherwise.
friend class SymbolRef; friend class SymbolRef;
virtual SymbolRef getSymbolNext(DataRefImpl Symb) const = 0; virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
virtual StringRef getSymbolName(DataRefImpl Symb) const = 0; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
virtual uint64_t getSymbolAddress(DataRefImpl Symb) const = 0; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
virtual char getSymbolNMTypeChar(DataRefImpl Symb) const = 0; virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
virtual bool isSymbolInternal(DataRefImpl Symb) const = 0; virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0;
// Same as above for SectionRef. // Same as above for SectionRef.
friend class SectionRef; friend class SectionRef;
virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
virtual StringRef getSectionName(DataRefImpl Sec) const = 0; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0; virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0; virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
virtual StringRef getSectionContents(DataRefImpl Sec) const = 0; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
virtual bool isSectionText(DataRefImpl Sec) const = 0; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
bool &Result) const = 0;
public: public:
@ -139,6 +172,10 @@ public:
return &Current; return &Current;
} }
const content_type &operator*() const {
return Current;
}
bool operator==(const content_iterator &other) const { bool operator==(const content_iterator &other) const {
return Current == other.Current; return Current == other.Current;
} }
@ -147,8 +184,12 @@ public:
return !(*this == other); return !(*this == other);
} }
content_iterator& operator++() { // Preincrement content_iterator& increment(error_code &err) {
Current = Current.getNext(); content_type next;
if (error_code ec = Current.getNext(next))
err = ec;
else
Current = next;
return *this; return *this;
} }
}; };
@ -156,8 +197,6 @@ public:
typedef content_iterator<SymbolRef> symbol_iterator; typedef content_iterator<SymbolRef> symbol_iterator;
typedef content_iterator<SectionRef> section_iterator; typedef content_iterator<SectionRef> section_iterator;
virtual ~ObjectFile();
virtual symbol_iterator begin_symbols() const = 0; virtual symbol_iterator begin_symbols() const = 0;
virtual symbol_iterator end_symbols() const = 0; virtual symbol_iterator end_symbols() const = 0;
@ -171,8 +210,6 @@ public:
virtual StringRef getFileFormatName() const = 0; virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0; virtual /* Triple::ArchType */ unsigned getArch() const = 0;
StringRef getFilename() const;
/// @returns Pointer to ObjectFile subclass to handle this type of object. /// @returns Pointer to ObjectFile subclass to handle this type of object.
/// @param ObjectPath The path to the object file. ObjectPath.isObject must /// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true. /// return true.
@ -180,12 +217,16 @@ public:
static ObjectFile *createObjectFile(StringRef ObjectPath); static ObjectFile *createObjectFile(StringRef ObjectPath);
static ObjectFile *createObjectFile(MemoryBuffer *Object); static ObjectFile *createObjectFile(MemoryBuffer *Object);
private: static inline bool classof(const Binary *v) {
return v->getType() >= isObject &&
v->getType() < lastObject;
}
static inline bool classof(const ObjectFile *v) { return true; }
public:
static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
static ObjectFile *createELFObjectFile(MemoryBuffer *Object); static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object); static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object);
static ObjectFile *createLibObjectFile(MemoryBuffer *Object);
}; };
// Inline function definitions. // Inline function definitions.
@ -197,28 +238,28 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const {
return SymbolPimpl == Other.SymbolPimpl; return SymbolPimpl == Other.SymbolPimpl;
} }
inline SymbolRef SymbolRef::getNext() const { inline error_code SymbolRef::getNext(SymbolRef &Result) const {
return OwningObject->getSymbolNext(SymbolPimpl); return OwningObject->getSymbolNext(SymbolPimpl, Result);
} }
inline StringRef SymbolRef::getName() const { inline error_code SymbolRef::getName(StringRef &Result) const {
return OwningObject->getSymbolName(SymbolPimpl); return OwningObject->getSymbolName(SymbolPimpl, Result);
} }
inline uint64_t SymbolRef::getAddress() const { inline error_code SymbolRef::getAddress(uint64_t &Result) const {
return OwningObject->getSymbolAddress(SymbolPimpl); return OwningObject->getSymbolAddress(SymbolPimpl, Result);
} }
inline uint64_t SymbolRef::getSize() const { inline error_code SymbolRef::getSize(uint64_t &Result) const {
return OwningObject->getSymbolSize(SymbolPimpl); return OwningObject->getSymbolSize(SymbolPimpl, Result);
} }
inline char SymbolRef::getNMTypeChar() const { inline error_code SymbolRef::getNMTypeChar(char &Result) const {
return OwningObject->getSymbolNMTypeChar(SymbolPimpl); return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
} }
inline bool SymbolRef::isInternal() const { inline error_code SymbolRef::isInternal(bool &Result) const {
return OwningObject->isSymbolInternal(SymbolPimpl); return OwningObject->isSymbolInternal(SymbolPimpl, Result);
} }
@ -232,28 +273,33 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
return SectionPimpl == Other.SectionPimpl; return SectionPimpl == Other.SectionPimpl;
} }
inline SectionRef SectionRef::getNext() const { inline error_code SectionRef::getNext(SectionRef &Result) const {
return OwningObject->getSectionNext(SectionPimpl); return OwningObject->getSectionNext(SectionPimpl, Result);
} }
inline StringRef SectionRef::getName() const { inline error_code SectionRef::getName(StringRef &Result) const {
return OwningObject->getSectionName(SectionPimpl); return OwningObject->getSectionName(SectionPimpl, Result);
} }
inline uint64_t SectionRef::getAddress() const { inline error_code SectionRef::getAddress(uint64_t &Result) const {
return OwningObject->getSectionAddress(SectionPimpl); return OwningObject->getSectionAddress(SectionPimpl, Result);
} }
inline uint64_t SectionRef::getSize() const { inline error_code SectionRef::getSize(uint64_t &Result) const {
return OwningObject->getSectionSize(SectionPimpl); return OwningObject->getSectionSize(SectionPimpl, Result);
} }
inline StringRef SectionRef::getContents() const { inline error_code SectionRef::getContents(StringRef &Result) const {
return OwningObject->getSectionContents(SectionPimpl); return OwningObject->getSectionContents(SectionPimpl, Result);
} }
inline bool SectionRef::isText() const { inline error_code SectionRef::isText(bool &Result) const {
return OwningObject->isSectionText(SectionPimpl); return OwningObject->isSectionText(SectionPimpl, Result);
}
inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
Result);
} }
} // end namespace object } // end namespace object

View File

@ -19,15 +19,9 @@
namespace llvm { namespace llvm {
class raw_ostream; class raw_ostream;
class BranchProbabilityInfo;
class MachineBranchProbabilityInfo;
class MachineBasicBlock;
// This class represents Branch Probability as a non-negative fraction. // This class represents Branch Probability as a non-negative fraction.
class BranchProbability { class BranchProbability {
friend class BranchProbabilityInfo;
friend class MachineBranchProbabilityInfo;
friend class MachineBasicBlock;
// Numerator // Numerator
uint32_t N; uint32_t N;
@ -35,9 +29,17 @@ class BranchProbability {
// Denominator // Denominator
uint32_t D; uint32_t D;
public:
BranchProbability(uint32_t n, uint32_t d); BranchProbability(uint32_t n, uint32_t d);
public: uint32_t getNumerator() const { return N; }
uint32_t getDenominator() const { return D; }
// Return (1 - Probability).
BranchProbability getCompl() {
return BranchProbability(D - N, D);
}
raw_ostream &print(raw_ostream &OS) const; raw_ostream &print(raw_ostream &OS) const;
void dump() const; void dump() const;

View File

@ -33,7 +33,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
USE_iterator It; USE_iterator It;
inline void advancePastNonTerminators() { inline void advancePastNonTerminators() {
// Loop to ignore non terminator uses (for example PHI nodes). // Loop to ignore non terminator uses (for example BlockAddresses).
while (!It.atEnd() && !isa<TerminatorInst>(*It)) while (!It.atEnd() && !isa<TerminatorInst>(*It))
++It; ++It;
} }
@ -109,11 +109,18 @@ public:
// TODO: This can be random access iterator, only operator[] missing. // TODO: This can be random access iterator, only operator[] missing.
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
assert(T && "getTerminator returned null!");
} }
inline SuccIterator(Term_ T, bool) // end iterator inline SuccIterator(Term_ T, bool) // end iterator
: Term(T), idx(Term->getNumSuccessors()) { : Term(T) {
assert(T && "getTerminator returned null!"); if (Term)
idx = Term->getNumSuccessors();
else
// Term == NULL happens, if a basic block is not fully constructed and
// consequently getTerminator() returns NULL. In this case we construct a
// SuccIterator which describes a basic block that has zero successors.
// Defining SuccIterator for incomplete and malformed CFGs is especially
// useful for debugging.
idx = 0;
} }
inline const Self &operator=(const Self &I) { inline const Self &operator=(const Self &I) {
@ -201,6 +208,7 @@ public:
/// Get the source BB of this iterator. /// Get the source BB of this iterator.
inline BB_ *getSource() { inline BB_ *getSource() {
assert(Term && "Source not available, if basic block was malformed");
return Term->getParent(); return Term->getParent();
} }
}; };

View File

@ -210,14 +210,14 @@ public:
return ConstantExpr::getShuffleVector(V1, V2, Mask); return ConstantExpr::getShuffleVector(V1, V2, Mask);
} }
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList, Constant *CreateExtractValue(Constant *Agg,
unsigned NumIdx) const { ArrayRef<unsigned> IdxList) const {
return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx); return ConstantExpr::getExtractValue(Agg, IdxList);
} }
Constant *CreateInsertValue(Constant *Agg, Constant *Val, Constant *CreateInsertValue(Constant *Agg, Constant *Val,
const unsigned *IdxList, unsigned NumIdx) const { ArrayRef<unsigned> IdxList) const {
return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx); return ConstantExpr::getInsertValue(Agg, Val, IdxList);
} }
}; };

View File

@ -61,7 +61,10 @@ namespace llvm {
/// getFromDILocation - Translate the DILocation quad into a DebugLoc. /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
static DebugLoc getFromDILocation(MDNode *N); static DebugLoc getFromDILocation(MDNode *N);
/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
static DebugLoc getFromDILexicalBlock(MDNode *N);
/// isUnknown - Return true if this is an unknown location. /// isUnknown - Return true if this is an unknown location.
bool isUnknown() const { return ScopeIdx == 0; } bool isUnknown() const { return ScopeIdx == 0; }
@ -94,6 +97,8 @@ namespace llvm {
return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx; return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
} }
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
void dump(const LLVMContext &Ctx) const;
}; };
template <> template <>

View File

@ -487,11 +487,11 @@ enum {
SHT_REL = 9, // Relocation entries; no explicit addends. SHT_REL = 9, // Relocation entries; no explicit addends.
SHT_SHLIB = 10, // Reserved. SHT_SHLIB = 10, // Reserved.
SHT_DYNSYM = 11, // Symbol table. SHT_DYNSYM = 11, // Symbol table.
SHT_INIT_ARRAY = 14, // Pointers to initialisation functions. SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
SHT_FINI_ARRAY = 15, // Pointers to termination functions. SHT_FINI_ARRAY = 15, // Pointers to termination functions.
SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
SHT_GROUP = 17, // Section group. SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indicies for SHN_XINDEX entries. SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type. SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type. SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
@ -630,7 +630,7 @@ enum {
STT_FUNC = 2, // Symbol is executable code (function, etc.) STT_FUNC = 2, // Symbol is executable code (function, etc.)
STT_SECTION = 3, // Symbol refers to a section STT_SECTION = 3, // Symbol refers to a section
STT_FILE = 4, // Local, absolute symbol that refers to a file STT_FILE = 4, // Local, absolute symbol that refers to a file
STT_COMMON = 5, // An uninitialised common block STT_COMMON = 5, // An uninitialized common block
STT_TLS = 6, // Thread local data object STT_TLS = 6, // Thread local data object
STT_LOPROC = 13, // Lowest processor-specific symbol type STT_LOPROC = 13, // Lowest processor-specific symbol type
STT_HIPROC = 15 // Highest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type
@ -804,7 +804,7 @@ enum {
DT_RELENT = 19, // Size of a Rel relocation entry. DT_RELENT = 19, // Size of a Rel relocation entry.
DT_PLTREL = 20, // Type of relocation entry used for linking. DT_PLTREL = 20, // Type of relocation entry used for linking.
DT_DEBUG = 21, // Reserved for debugger. DT_DEBUG = 21, // Reserved for debugger.
DT_TEXTREL = 22, // Relocations exist for non-writable segements. DT_TEXTREL = 22, // Relocations exist for non-writable segments.
DT_JMPREL = 23, // Address of relocations associated with PLT. DT_JMPREL = 23, // Address of relocations associated with PLT.
DT_BIND_NOW = 24, // Process all relocations before execution. DT_BIND_NOW = 24, // Process all relocations before execution.
DT_INIT_ARRAY = 25, // Pointer to array of initialization functions. DT_INIT_ARRAY = 25, // Pointer to array of initialization functions.

View File

@ -14,7 +14,6 @@
#ifndef LLVM_SUPPORT_ENDIAN_H #ifndef LLVM_SUPPORT_ENDIAN_H
#define LLVM_SUPPORT_ENDIAN_H #define LLVM_SUPPORT_ENDIAN_H
#include "llvm/Config/config.h"
#include "llvm/Support/Host.h" #include "llvm/Support/Host.h"
#include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h" #include "llvm/Support/type_traits.h"

View File

@ -82,7 +82,7 @@ public:
InsertPt = I; InsertPt = I;
SetCurrentDebugLocation(I->getDebugLoc()); SetCurrentDebugLocation(I->getDebugLoc());
} }
/// SetInsertPoint - This specifies that created instructions should be /// SetInsertPoint - This specifies that created instructions should be
/// inserted at the specified point. /// inserted at the specified point.
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
@ -90,6 +90,19 @@ public:
InsertPt = IP; InsertPt = IP;
} }
/// SetInsertPoint(Use) - Find the nearest point that dominates this use, and
/// specify that created instructions should be inserted at this point.
void SetInsertPoint(Use &U) {
Instruction *UseInst = cast<Instruction>(U.getUser());
if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
BasicBlock *PredBB = Phi->getIncomingBlock(U);
assert(U != PredBB->getTerminator() && "critical edge not split");
SetInsertPoint(PredBB, PredBB->getTerminator());
return;
}
SetInsertPoint(UseInst);
}
/// SetCurrentDebugLocation - Set location information used by debugging /// SetCurrentDebugLocation - Set location information used by debugging
/// information. /// information.
void SetCurrentDebugLocation(const DebugLoc &L) { void SetCurrentDebugLocation(const DebugLoc &L) {
@ -98,7 +111,7 @@ public:
/// getCurrentDebugLocation - Get location information used by debugging /// getCurrentDebugLocation - Get location information used by debugging
/// information. /// information.
const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
/// SetInstDebugLocation - If this builder has a current debug location, set /// SetInstDebugLocation - If this builder has a current debug location, set
/// it on the specified instruction. /// it on the specified instruction.
@ -109,8 +122,8 @@ public:
/// getCurrentFunctionReturnType - Get the return type of the current function /// getCurrentFunctionReturnType - Get the return type of the current function
/// that we're emitting into. /// that we're emitting into.
const Type *getCurrentFunctionReturnType() const; Type *getCurrentFunctionReturnType() const;
/// InsertPoint - A saved insertion point. /// InsertPoint - A saved insertion point.
class InsertPoint { class InsertPoint {
BasicBlock *Block; BasicBlock *Block;
@ -198,7 +211,7 @@ public:
ConstantInt *getInt64(uint64_t C) { ConstantInt *getInt64(uint64_t C) {
return ConstantInt::get(getInt64Ty(), C); return ConstantInt::get(getInt64Ty(), C);
} }
/// getInt - Get a constant integer value. /// getInt - Get a constant integer value.
ConstantInt *getInt(const APInt &AI) { ConstantInt *getInt(const APInt &AI) {
return ConstantInt::get(Context, AI); return ConstantInt::get(Context, AI);
@ -209,46 +222,46 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// getInt1Ty - Fetch the type representing a single bit /// getInt1Ty - Fetch the type representing a single bit
const IntegerType *getInt1Ty() { IntegerType *getInt1Ty() {
return Type::getInt1Ty(Context); return Type::getInt1Ty(Context);
} }
/// getInt8Ty - Fetch the type representing an 8-bit integer. /// getInt8Ty - Fetch the type representing an 8-bit integer.
const IntegerType *getInt8Ty() { IntegerType *getInt8Ty() {
return Type::getInt8Ty(Context); return Type::getInt8Ty(Context);
} }
/// getInt16Ty - Fetch the type representing a 16-bit integer. /// getInt16Ty - Fetch the type representing a 16-bit integer.
const IntegerType *getInt16Ty() { IntegerType *getInt16Ty() {
return Type::getInt16Ty(Context); return Type::getInt16Ty(Context);
} }
/// getInt32Ty - Fetch the type resepresenting a 32-bit integer. /// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
const IntegerType *getInt32Ty() { IntegerType *getInt32Ty() {
return Type::getInt32Ty(Context); return Type::getInt32Ty(Context);
} }
/// getInt64Ty - Fetch the type representing a 64-bit integer. /// getInt64Ty - Fetch the type representing a 64-bit integer.
const IntegerType *getInt64Ty() { IntegerType *getInt64Ty() {
return Type::getInt64Ty(Context); return Type::getInt64Ty(Context);
} }
/// getFloatTy - Fetch the type representing a 32-bit floating point value. /// getFloatTy - Fetch the type representing a 32-bit floating point value.
const Type *getFloatTy() { Type *getFloatTy() {
return Type::getFloatTy(Context); return Type::getFloatTy(Context);
} }
/// getDoubleTy - Fetch the type representing a 64-bit floating point value. /// getDoubleTy - Fetch the type representing a 64-bit floating point value.
const Type *getDoubleTy() { Type *getDoubleTy() {
return Type::getDoubleTy(Context); return Type::getDoubleTy(Context);
} }
/// getVoidTy - Fetch the type representing void. /// getVoidTy - Fetch the type representing void.
const Type *getVoidTy() { Type *getVoidTy() {
return Type::getVoidTy(Context); return Type::getVoidTy(Context);
} }
const PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
return Type::getInt8PtrTy(Context, AddrSpace); return Type::getInt8PtrTy(Context, AddrSpace);
} }
@ -263,7 +276,7 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) { bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag); return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
} }
CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0); bool isVolatile = false, MDNode *TBAATag = 0);
@ -274,7 +287,7 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) { bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
} }
CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0); bool isVolatile = false, MDNode *TBAATag = 0);
@ -285,9 +298,9 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) { bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
} }
CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0); bool isVolatile = false, MDNode *TBAATag = 0);
/// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
/// isn't i8* it will be converted. /// isn't i8* it will be converted.
@ -341,7 +354,13 @@ public:
SetInsertPoint(IP); SetInsertPoint(IP);
SetCurrentDebugLocation(IP->getDebugLoc()); SetCurrentDebugLocation(IP->getDebugLoc());
} }
explicit IRBuilder(Use &U)
: IRBuilderBase(U->getContext()), Folder() {
SetInsertPoint(U);
SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
: IRBuilderBase(TheBB->getContext()), Folder(F) { : IRBuilderBase(TheBB->getContext()), Folder(F) {
SetInsertPoint(TheBB, IP); SetInsertPoint(TheBB, IP);
@ -430,34 +449,30 @@ public:
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, const Twine &Name = "") { BasicBlock *UnwindDest, const Twine &Name = "") {
Value *Args[] = { 0 }; return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, ArrayRef<Value *>()),
Args), Name); Name);
} }
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, Value *Arg1, BasicBlock *UnwindDest, Value *Arg1,
const Twine &Name = "") { const Twine &Name = "") {
Value *Args[] = { Arg1 }; return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, Name);
Args+1), Name);
} }
InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, Value *Arg1, BasicBlock *UnwindDest, Value *Arg1,
Value *Arg2, Value *Arg3, Value *Arg2, Value *Arg3,
const Twine &Name = "") { const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3 }; Value *Args[] = { Arg1, Arg2, Arg3 };
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
Args+3), Name); Name);
} }
/// CreateInvoke - Create an invoke instruction. /// CreateInvoke - Create an invoke instruction.
template<typename RandomAccessIterator>
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, BasicBlock *UnwindDest, ArrayRef<Value *> Args,
RandomAccessIterator ArgBegin,
RandomAccessIterator ArgEnd,
const Twine &Name = "") { const Twine &Name = "") {
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
ArgBegin, ArgEnd), Name); Name);
} }
UnwindInst *CreateUnwind() { UnwindInst *CreateUnwind() {
@ -1107,33 +1122,27 @@ public:
CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2, CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
const Twine &Name = "") { const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2 }; Value *Args[] = { Arg1, Arg2 };
return Insert(CallInst::Create(Callee, Args, Args+2), Name); return Insert(CallInst::Create(Callee, Args), Name);
} }
CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
const Twine &Name = "") { const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3 }; Value *Args[] = { Arg1, Arg2, Arg3 };
return Insert(CallInst::Create(Callee, Args, Args+3), Name); return Insert(CallInst::Create(Callee, Args), Name);
} }
CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
Value *Arg4, const Twine &Name = "") { Value *Arg4, const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3, Arg4 }; Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
return Insert(CallInst::Create(Callee, Args, Args+4), Name); return Insert(CallInst::Create(Callee, Args), Name);
} }
CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
Value *Arg4, Value *Arg5, const Twine &Name = "") { Value *Arg4, Value *Arg5, const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 }; Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
return Insert(CallInst::Create(Callee, Args, Args+5), Name); return Insert(CallInst::Create(Callee, Args), Name);
} }
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Arg, CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
const Twine &Name = "") { const Twine &Name = "") {
return Insert(CallInst::Create(Callee, Arg.begin(), Arg.end(), Name)); return Insert(CallInst::Create(Callee, Args, Name));
}
template<typename RandomAccessIterator>
CallInst *CreateCall(Value *Callee, RandomAccessIterator ArgBegin,
RandomAccessIterator ArgEnd, const Twine &Name = "") {
return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name);
} }
Value *CreateSelect(Value *C, Value *True, Value *False, Value *CreateSelect(Value *C, Value *True, Value *False,
@ -1175,43 +1184,21 @@ public:
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
} }
Value *CreateExtractValue(Value *Agg, unsigned Idx,
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
return Insert(Folder.CreateExtractValue(AggC, &Idx, 1), Name);
return Insert(ExtractValueInst::Create(Agg, Idx), Name);
}
template<typename RandomAccessIterator>
Value *CreateExtractValue(Value *Agg, Value *CreateExtractValue(Value *Agg,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &Name = "") { const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg)) if (Constant *AggC = dyn_cast<Constant>(Agg))
return Insert(Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd-IdxBegin), return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
Name); return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
} }
Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx,
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val))
return Insert(Folder.CreateInsertValue(AggC, ValC, &Idx, 1), Name);
return Insert(InsertValueInst::Create(Agg, Val, Idx), Name);
}
template<typename RandomAccessIterator>
Value *CreateInsertValue(Value *Agg, Value *Val, Value *CreateInsertValue(Value *Agg, Value *Val,
RandomAccessIterator IdxBegin, ArrayRef<unsigned> Idxs,
RandomAccessIterator IdxEnd,
const Twine &Name = "") { const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg)) if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val)) if (Constant *ValC = dyn_cast<Constant>(Val))
return Insert(Folder.CreateInsertValue(AggC, ValC, IdxBegin, return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
IdxEnd - IdxBegin), return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
Name);
return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -1238,7 +1225,7 @@ public:
Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
assert(LHS->getType() == RHS->getType() && assert(LHS->getType() == RHS->getType() &&
"Pointer subtraction operand types must match!"); "Pointer subtraction operand types must match!");
const PointerType *ArgType = cast<PointerType>(LHS->getType()); PointerType *ArgType = cast<PointerType>(LHS->getType());
Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
Value *Difference = CreateSub(LHS_int, RHS_int); Value *Difference = CreateSub(LHS_int, RHS_int);

View File

@ -22,6 +22,7 @@
#ifndef LLVM_SUPPORT_NOFOLDER_H #ifndef LLVM_SUPPORT_NOFOLDER_H
#define LLVM_SUPPORT_NOFOLDER_H #define LLVM_SUPPORT_NOFOLDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
@ -269,15 +270,14 @@ public:
return new ShuffleVectorInst(V1, V2, Mask); return new ShuffleVectorInst(V1, V2, Mask);
} }
Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList, Instruction *CreateExtractValue(Constant *Agg,
unsigned NumIdx) const { ArrayRef<unsigned> IdxList) const {
return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx); return ExtractValueInst::Create(Agg, IdxList);
} }
Instruction *CreateInsertValue(Constant *Agg, Constant *Val, Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
const unsigned *IdxList, ArrayRef<unsigned> IdxList) const {
unsigned NumIdx) const { return InsertValueInst::Create(Agg, Val, IdxList);
return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
} }
}; };

View File

@ -67,7 +67,12 @@ public:
/// EP_LoopOptimizerEnd - This extension point allows adding loop passes to /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
/// the end of the loop optimizer. /// the end of the loop optimizer.
EP_LoopOptimizerEnd EP_LoopOptimizerEnd,
/// EP_ScalarOptimizerLate - This extension point allows adding optimization
/// passes after most of the main optimizations, but before the last
/// cleanup-ish optimizations.
EP_ScalarOptimizerLate
}; };
/// The Optimization Level - Specify the basic optimization level. /// The Optimization Level - Specify the basic optimization level.
@ -147,6 +152,7 @@ public:
FPM.add(createCFGSimplificationPass()); FPM.add(createCFGSimplificationPass());
FPM.add(createScalarReplAggregatesPass()); FPM.add(createScalarReplAggregatesPass());
FPM.add(createEarlyCSEPass()); FPM.add(createEarlyCSEPass());
FPM.add(createLowerExpectIntrinsicPass());
} }
/// populateModulePassManager - This sets up the primary pass manager. /// populateModulePassManager - This sets up the primary pass manager.
@ -223,13 +229,16 @@ public:
MPM.add(createJumpThreadingPass()); // Thread jumps MPM.add(createJumpThreadingPass()); // Thread jumps
MPM.add(createCorrelatedValuePropagationPass()); MPM.add(createCorrelatedValuePropagationPass());
MPM.add(createDeadStoreEliminationPass()); // Delete dead stores MPM.add(createDeadStoreEliminationPass()); // Delete dead stores
addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
MPM.add(createAggressiveDCEPass()); // Delete dead instructions MPM.add(createAggressiveDCEPass()); // Delete dead instructions
MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
MPM.add(createInstructionCombiningPass()); // Clean up after everything. MPM.add(createInstructionCombiningPass()); // Clean up after everything.
if (!DisableUnitAtATime) { if (!DisableUnitAtATime) {
// FIXME: We shouldn't bother with this anymore.
MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
MPM.add(createDeadTypeEliminationPass()); // Eliminate dead types
// GlobalOpt already deletes dead functions and globals, at -O3 try a // GlobalOpt already deletes dead functions and globals, at -O3 try a
// late pass of GlobalDCE. It is capable of deleting dead cycles. // late pass of GlobalDCE. It is capable of deleting dead cycles.

View File

@ -21,6 +21,7 @@
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/InstrTypes.h" #include "llvm/InstrTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ConstantFolding.h"
namespace llvm { namespace llvm {
@ -226,14 +227,14 @@ public:
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
} }
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList, Constant *CreateExtractValue(Constant *Agg,
unsigned NumIdx) const { ArrayRef<unsigned> IdxList) const {
return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx)); return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
} }
Constant *CreateInsertValue(Constant *Agg, Constant *Val, Constant *CreateInsertValue(Constant *Agg, Constant *Val,
const unsigned *IdxList, unsigned NumIdx) const { ArrayRef<unsigned> IdxList) const {
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx)); return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
} }
}; };

View File

@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include <limits.h> #include <limits.h>
#include <vector>
namespace llvm { namespace llvm {
@ -50,7 +51,7 @@ namespace llvm {
/// namespace llvm { /// namespace llvm {
/// template<bool xcompile> class TypeBuilder<MyType, xcompile> { /// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
/// public: /// public:
/// static const StructType *get(LLVMContext &Context) { /// static StructType *get(LLVMContext &Context) {
/// // If you cache this result, be sure to cache it separately /// // If you cache this result, be sure to cache it separately
/// // for each LLVMContext. /// // for each LLVMContext.
/// return StructType::get( /// return StructType::get(
@ -103,7 +104,7 @@ template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
// Pointers // Pointers
template<typename T, bool cross> class TypeBuilder<T*, cross> { template<typename T, bool cross> class TypeBuilder<T*, cross> {
public: public:
static const PointerType *get(LLVMContext &Context) { static PointerType *get(LLVMContext &Context) {
return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
} }
}; };
@ -114,14 +115,14 @@ template<typename T, bool cross> class TypeBuilder<T&, cross> {};
// Arrays // Arrays
template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
public: public:
static const ArrayType *get(LLVMContext &Context) { static ArrayType *get(LLVMContext &Context) {
return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
} }
}; };
/// LLVM uses an array of length 0 to represent an unknown-length array. /// LLVM uses an array of length 0 to represent an unknown-length array.
template<typename T, bool cross> class TypeBuilder<T[], cross> { template<typename T, bool cross> class TypeBuilder<T[], cross> {
public: public:
static const ArrayType *get(LLVMContext &Context) { static ArrayType *get(LLVMContext &Context) {
return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
} }
}; };
@ -151,7 +152,7 @@ public:
#define DEFINE_INTEGRAL_TYPEBUILDER(T) \ #define DEFINE_INTEGRAL_TYPEBUILDER(T) \
template<> class TypeBuilder<T, false> { \ template<> class TypeBuilder<T, false> { \
public: \ public: \
static const IntegerType *get(LLVMContext &Context) { \ static IntegerType *get(LLVMContext &Context) { \
return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
} \ } \
}; \ }; \
@ -180,14 +181,14 @@ DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
template<uint32_t num_bits, bool cross> template<uint32_t num_bits, bool cross>
class TypeBuilder<types::i<num_bits>, cross> { class TypeBuilder<types::i<num_bits>, cross> {
public: public:
static const IntegerType *get(LLVMContext &C) { static IntegerType *get(LLVMContext &C) {
return IntegerType::get(C, num_bits); return IntegerType::get(C, num_bits);
} }
}; };
template<> class TypeBuilder<float, false> { template<> class TypeBuilder<float, false> {
public: public:
static const Type *get(LLVMContext& C) { static Type *get(LLVMContext& C) {
return Type::getFloatTy(C); return Type::getFloatTy(C);
} }
}; };
@ -195,7 +196,7 @@ template<> class TypeBuilder<float, true> {};
template<> class TypeBuilder<double, false> { template<> class TypeBuilder<double, false> {
public: public:
static const Type *get(LLVMContext& C) { static Type *get(LLVMContext& C) {
return Type::getDoubleTy(C); return Type::getDoubleTy(C);
} }
}; };
@ -203,32 +204,32 @@ template<> class TypeBuilder<double, true> {};
template<bool cross> class TypeBuilder<types::ieee_float, cross> { template<bool cross> class TypeBuilder<types::ieee_float, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getFloatTy(C); } static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
}; };
template<bool cross> class TypeBuilder<types::ieee_double, cross> { template<bool cross> class TypeBuilder<types::ieee_double, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
}; };
template<bool cross> class TypeBuilder<types::x86_fp80, cross> { template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
}; };
template<bool cross> class TypeBuilder<types::fp128, cross> { template<bool cross> class TypeBuilder<types::fp128, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
}; };
template<bool cross> class TypeBuilder<types::ppc_fp128, cross> { template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
}; };
template<bool cross> class TypeBuilder<types::x86_mmx, cross> { template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
public: public:
static const Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); } static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
}; };
template<bool cross> class TypeBuilder<void, cross> { template<bool cross> class TypeBuilder<void, cross> {
public: public:
static const Type *get(LLVMContext &C) { static Type *get(LLVMContext &C) {
return Type::getVoidTy(C); return Type::getVoidTy(C);
} }
}; };
@ -246,14 +247,14 @@ template<> class TypeBuilder<const volatile void*, false>
template<typename R, bool cross> class TypeBuilder<R(), cross> { template<typename R, bool cross> class TypeBuilder<R(), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
} }
}; };
template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(1); params.reserve(1);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
return FunctionType::get(TypeBuilder<R, cross>::get(Context), return FunctionType::get(TypeBuilder<R, cross>::get(Context),
@ -263,8 +264,8 @@ public:
template<typename R, typename A1, typename A2, bool cross> template<typename R, typename A1, typename A2, bool cross>
class TypeBuilder<R(A1, A2), cross> { class TypeBuilder<R(A1, A2), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(2); params.reserve(2);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -275,8 +276,8 @@ public:
template<typename R, typename A1, typename A2, typename A3, bool cross> template<typename R, typename A1, typename A2, typename A3, bool cross>
class TypeBuilder<R(A1, A2, A3), cross> { class TypeBuilder<R(A1, A2, A3), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(3); params.reserve(3);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -290,8 +291,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
bool cross> bool cross>
class TypeBuilder<R(A1, A2, A3, A4), cross> { class TypeBuilder<R(A1, A2, A3, A4), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(4); params.reserve(4);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -306,8 +307,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, bool cross> typename A5, bool cross>
class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(5); params.reserve(5);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -321,15 +322,15 @@ public:
template<typename R, bool cross> class TypeBuilder<R(...), cross> { template<typename R, bool cross> class TypeBuilder<R(...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
} }
}; };
template<typename R, typename A1, bool cross> template<typename R, typename A1, bool cross>
class TypeBuilder<R(A1, ...), cross> { class TypeBuilder<R(A1, ...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(1); params.reserve(1);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
@ -338,8 +339,8 @@ public:
template<typename R, typename A1, typename A2, bool cross> template<typename R, typename A1, typename A2, bool cross>
class TypeBuilder<R(A1, A2, ...), cross> { class TypeBuilder<R(A1, A2, ...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(2); params.reserve(2);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -350,8 +351,8 @@ public:
template<typename R, typename A1, typename A2, typename A3, bool cross> template<typename R, typename A1, typename A2, typename A3, bool cross>
class TypeBuilder<R(A1, A2, A3, ...), cross> { class TypeBuilder<R(A1, A2, A3, ...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(3); params.reserve(3);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -365,8 +366,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
bool cross> bool cross>
class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(4); params.reserve(4);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));
@ -381,8 +382,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, bool cross> typename A5, bool cross>
class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
public: public:
static const FunctionType *get(LLVMContext &Context) { static FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params; std::vector<Type*> params;
params.reserve(5); params.reserve(5);
params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A1, cross>::get(Context));
params.push_back(TypeBuilder<A2, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context));

View File

@ -222,7 +222,7 @@ template <> struct hash<std::error_code>;
*/ */
#include "llvm/Config/config.h" #include "llvm/Config/llvm-config.h"
#include "llvm/Support/type_traits.h" #include "llvm/Support/type_traits.h"
#include <cerrno> #include <cerrno>
#include <string> #include <string>
@ -669,7 +669,7 @@ const error_category& generic_category();
const error_category& system_category(); const error_category& system_category();
/// Get the error_category used for errno values from POSIX functions. This is /// Get the error_category used for errno values from POSIX functions. This is
/// the same as the system_category on POISIX systems, but is the same as the /// the same as the system_category on POSIX systems, but is the same as the
/// generic_category on Windows. /// generic_category on Windows.
const error_category& posix_category(); const error_category& posix_category();

View File

@ -26,11 +26,19 @@ class SubRegIndex {
string Namespace = ""; string Namespace = "";
} }
// RegAltNameIndex - The alternate name set to use for register operands of
// this register class when printing.
class RegAltNameIndex {
string Namespace = "";
}
def NoRegAltName : RegAltNameIndex;
// Register - You should define one instance of this class for each register // Register - You should define one instance of this class for each register
// in the target machine. String n will become the "name" of the register. // in the target machine. String n will become the "name" of the register.
class Register<string n> { class Register<string n, list<string> altNames = []> {
string Namespace = ""; string Namespace = "";
string AsmName = n; string AsmName = n;
list<string> AltNames = altNames;
// Aliases - A list of registers that this register overlaps with. A read or // Aliases - A list of registers that this register overlaps with. A read or
// modification of this register can potentially read or modify the aliased // modification of this register can potentially read or modify the aliased
@ -48,6 +56,10 @@ class Register<string n> {
// SubRegs. // SubRegs.
list<SubRegIndex> SubRegIndices = []; list<SubRegIndex> SubRegIndices = [];
// RegAltNameIndices - The alternate name indices which are valid for this
// register.
list<RegAltNameIndex> RegAltNameIndices = [];
// CompositeIndices - Specify subreg indices that don't correspond directly to // CompositeIndices - Specify subreg indices that don't correspond directly to
// a register in SubRegs and are not inherited. The following formats are // a register in SubRegs and are not inherited. The following formats are
// supported: // supported:
@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
// registers by register allocators. // registers by register allocators.
// //
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
list<Register> regList> { dag regList, RegAltNameIndex idx = NoRegAltName> {
string Namespace = namespace; string Namespace = namespace;
// RegType - Specify the list ValueType of the registers in this register // RegType - Specify the list ValueType of the registers in this register
@ -122,7 +134,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// allocation_order_* method are not specified, this also defines the order of // allocation_order_* method are not specified, this also defines the order of
// allocation used by the register allocator. // allocation used by the register allocator.
// //
list<Register> MemberList = regList; dag MemberList = regList;
// AltNameIndex - The alternate register name to use when printing operands
// of this register class. Every register in the register class must have
// a valid alternate name for the given index.
RegAltNameIndex altNameIndex = idx;
// SubRegClasses - Specify the register class of subregisters as a list of // SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...) // dags: (RegClass SubRegIndex, SubRegindex, ...)
@ -133,11 +150,91 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// model instruction operand constraints, and should have isAllocatable = 0. // model instruction operand constraints, and should have isAllocatable = 0.
bit isAllocatable = 1; bit isAllocatable = 1;
// MethodProtos/MethodBodies - These members can be used to insert arbitrary // AltOrders - List of alternative allocation orders. The default order is
// code into a generated register class. The normal usage of this is to // MemberList itself, and that is good enough for most targets since the
// overload virtual methods. // register allocators automatically remove reserved registers and move
code MethodProtos = [{}]; // callee-saved registers to the end.
code MethodBodies = [{}]; list<dag> AltOrders = [];
// AltOrderSelect - The body of a function that selects the allocation order
// to use in a given machine function. The code will be inserted in a
// function like this:
//
// static inline unsigned f(const MachineFunction &MF) { ... }
//
// The function should return 0 to select the default order defined by
// MemberList, 1 to select the first AltOrders entry and so on.
code AltOrderSelect = [{}];
}
// The memberList in a RegisterClass is a dag of set operations. TableGen
// evaluates these set operations and expand them into register lists. These
// are the most common operation, see test/TableGen/SetTheory.td for more
// examples of what is possible:
//
// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a
// register class, or a sub-expression. This is also the way to simply list
// registers.
//
// (sub GPR, SP) - Set difference. Subtract the last arguments from the first.
//
// (and GPR, CSR) - Set intersection. All registers from the first set that are
// also in the second set.
//
// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
// numbered registers.
//
// (shl GPR, 4) - Remove the first N elements.
//
// (trunc GPR, 4) - Truncate after the first N elements.
//
// (rotl GPR, 1) - Rotate N places to the left.
//
// (rotr GPR, 1) - Rotate N places to the right.
//
// (decimate GPR, 2) - Pick every N'th element, starting with the first.
//
// All of these operators work on ordered sets, not lists. That means
// duplicates are removed from sub-expressions.
// Set operators. The rest is defined in TargetSelectionDAG.td.
def sequence;
def decimate;
// RegisterTuples - Automatically generate super-registers by forming tuples of
// sub-registers. This is useful for modeling register sequence constraints
// with pseudo-registers that are larger than the architectural registers.
//
// The sub-register lists are zipped together:
//
// def EvenOdd : RegisterTuples<[sube, subo], [(add R0, R2), (add R1, R3)]>;
//
// Generates the same registers as:
//
// let SubRegIndices = [sube, subo] in {
// def R0_R1 : RegisterWithSubRegs<"", [R0, R1]>;
// def R2_R3 : RegisterWithSubRegs<"", [R2, R3]>;
// }
//
// The generated pseudo-registers inherit super-classes and fields from their
// first sub-register. Most fields from the Register class are inferred, and
// the AsmName and Dwarf numbers are cleared.
//
// RegisterTuples instances can be used in other set operations to form
// register classes and so on. This is the only way of using the generated
// registers.
class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> {
// SubRegs - N lists of registers to be zipped up. Super-registers are
// synthesized from the first element of each SubRegs list, the second
// element and so on.
list<dag> SubRegs = Regs;
// SubRegIndices - N SubRegIndex instances. This provides the names of the
// sub-registers in the synthesized super-registers.
list<SubRegIndex> SubRegIndices = Indices;
// Compose sub-register indices like in a normal Register.
list<dag> CompositeIndices = [];
} }
@ -196,7 +293,12 @@ class Instruction {
// code. // code.
list<Predicate> Predicates = []; list<Predicate> Predicates = [];
// Code size. // Size - Size of encoded instruction, or zero if the size cannot be determined
// from the opcode.
int Size = 0;
// Code size, for instruction selection.
// FIXME: What does this actually mean?
int CodeSize = 0; int CodeSize = 0;
// Added complexity passed onto matching pattern. // Added complexity passed onto matching pattern.
@ -227,6 +329,9 @@ class Instruction {
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
bit isPseudo = 0; // Is this instruction a pseudo-instruction?
// If so, won't have encoding information for
// the [MC]CodeEmitter stuff.
// Side effect flags - When set, the flags have these meanings: // Side effect flags - When set, the flags have these meanings:
// //
@ -241,6 +346,11 @@ class Instruction {
// Is this instruction a "real" instruction (with a distinct machine // Is this instruction a "real" instruction (with a distinct machine
// encoding), or is it a pseudo instruction used for codegen modeling // encoding), or is it a pseudo instruction used for codegen modeling
// purposes. // purposes.
// FIXME: For now this is distinct from isPseudo, above, as code-gen-only
// instructions can (and often do) still have encoding information
// associated with them. Once we've migrated all of them over to true
// pseudo-instructions that are lowered to real instructions prior to
// the printer/emitter, we can remove this attribute and just use isPseudo.
bit isCodeGenOnly = 0; bit isCodeGenOnly = 0;
// Is this instruction a pseudo instruction for use by the assembler parser. // Is this instruction a pseudo instruction for use by the assembler parser.
@ -268,6 +378,14 @@ class Instruction {
///@} ///@}
} }
/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
/// Which instruction it expands to and how the operands map from the
/// pseudo.
class PseudoInstExpansion<dag Result> {
dag ResultInst = Result; // The instruction to generate.
bit isPseudo = 1;
}
/// Predicates - These are extra conditionals which are turned into instruction /// Predicates - These are extra conditionals which are turned into instruction
/// selector matching code. Currently each predicate is just a string. /// selector matching code. Currently each predicate is just a string.
class Predicate<string cond> { class Predicate<string cond> {
@ -277,6 +395,15 @@ class Predicate<string cond> {
/// matcher, this is true. Targets should set this by inheriting their /// matcher, this is true. Targets should set this by inheriting their
/// feature from the AssemblerPredicate class in addition to Predicate. /// feature from the AssemblerPredicate class in addition to Predicate.
bit AssemblerMatcherPredicate = 0; bit AssemblerMatcherPredicate = 0;
/// AssemblerCondString - Name of the subtarget feature being tested used
/// as alternative condition string used for assembler matcher.
/// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0".
/// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0".
/// It can also list multiple features separated by ",".
/// e.g. "ModeThumb,FeatureThumb2" is translated to
/// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
string AssemblerCondString = "";
} }
/// NoHonorSignDependentRounding - This predicate is true if support for /// NoHonorSignDependentRounding - This predicate is true if support for
@ -373,6 +500,7 @@ class Operand<ValueType ty> {
string EncoderMethod = ""; string EncoderMethod = "";
string DecoderMethod = ""; string DecoderMethod = "";
string AsmOperandLowerMethod = ?; string AsmOperandLowerMethod = ?;
string OperandType = "OPERAND_UNKNOWN";
dag MIOperandInfo = (ops); dag MIOperandInfo = (ops);
// ParserMatchClass - The "match class" that operands of this type fit // ParserMatchClass - The "match class" that operands of this type fit
@ -386,6 +514,25 @@ class Operand<ValueType ty> {
AsmOperandClass ParserMatchClass = ImmAsmOperand; AsmOperandClass ParserMatchClass = ImmAsmOperand;
} }
class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
// RegClass - The register class of the operand.
RegisterClass RegClass = regclass;
// PrintMethod - The target method to call to print register operands of
// this type. The method normally will just use an alt-name index to look
// up the name to print. Default to the generic printOperand().
string PrintMethod = pm;
// ParserMatchClass - The "match class" that operands of this type fit
// in. Match classes are used to define the order in which instructions are
// match, to ensure that which instructions gets matched is deterministic.
//
// The target specific parser must be able to classify an parsed operand into
// a unique class, which does not partially overlap with any other classes. It
// can match a subset of some other class, in which case the AsmOperandClass
// should declare the other operand as one of its super classes.
AsmOperandClass ParserMatchClass;
}
let OperandType = "OPERAND_IMMEDIATE" in {
def i1imm : Operand<i1>; def i1imm : Operand<i1>;
def i8imm : Operand<i8>; def i8imm : Operand<i8>;
def i16imm : Operand<i16>; def i16imm : Operand<i16>;
@ -394,6 +541,7 @@ def i64imm : Operand<i64>;
def f32imm : Operand<f32>; def f32imm : Operand<f32>;
def f64imm : Operand<f64>; def f64imm : Operand<f64>;
}
/// zero_reg definition - Special node to stand for the zero register. /// zero_reg definition - Special node to stand for the zero register.
/// ///
@ -566,8 +714,9 @@ def DefaultAsmParser : AsmParser;
/// AssemblerPredicate - This is a Predicate that can be used when the assembler /// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases. /// matches instructions and aliases.
class AssemblerPredicate { class AssemblerPredicate<string cond> {
bit AssemblerMatcherPredicate = 1; bit AssemblerMatcherPredicate = 1;
string AssemblerCondString = cond;
} }

View File

@ -20,6 +20,7 @@
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
namespace llvm { namespace llvm {
template <typename T> class ArrayRef;
class MCSection; class MCSection;
class MCContext; class MCContext;
class MachineFunction; class MachineFunction;
@ -27,30 +28,14 @@ namespace llvm {
class TargetLoweringObjectFile; class TargetLoweringObjectFile;
class TargetAsmInfo { class TargetAsmInfo {
unsigned PointerSize;
bool IsLittleEndian;
TargetFrameLowering::StackDirection StackDir;
const TargetRegisterInfo *TRI;
std::vector<MachineMove> InitialFrameState; std::vector<MachineMove> InitialFrameState;
const TargetRegisterInfo *TRI;
const TargetFrameLowering *TFI;
const TargetLoweringObjectFile *TLOF; const TargetLoweringObjectFile *TLOF;
public: public:
explicit TargetAsmInfo(const TargetMachine &TM); explicit TargetAsmInfo(const TargetMachine &TM);
/// getPointerSize - Get the pointer size in bytes.
unsigned getPointerSize() const {
return PointerSize;
}
/// islittleendian - True if the target is little endian.
bool isLittleEndian() const {
return IsLittleEndian;
}
TargetFrameLowering::StackDirection getStackGrowthDirection() const {
return StackDir;
}
const MCSection *getDwarfLineSection() const { const MCSection *getDwarfLineSection() const {
return TLOF->getDwarfLineSection(); return TLOF->getDwarfLineSection();
} }
@ -59,6 +44,10 @@ public:
return TLOF->getEHFrameSection(); return TLOF->getEHFrameSection();
} }
const MCSection *getCompactUnwindSection() const {
return TLOF->getCompactUnwindSection();
}
const MCSection *getDwarfFrameSection() const { const MCSection *getDwarfFrameSection() const {
return TLOF->getDwarfFrameSection(); return TLOF->getDwarfFrameSection();
} }
@ -79,6 +68,12 @@ public:
return TLOF->isFunctionEHFrameSymbolPrivate(); return TLOF->isFunctionEHFrameSymbolPrivate();
} }
int getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs,
int DataAlignmentFactor,
bool IsEH) const {
return TFI->getCompactUnwindEncoding(Instrs, DataAlignmentFactor, IsEH);
}
const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const {
return TRI->getCalleeSavedRegs(MF); return TRI->getCalleeSavedRegs(MF);
} }

View File

@ -15,7 +15,6 @@
namespace llvm { namespace llvm {
class MCStreamer; class MCStreamer;
class StringRef; class StringRef;
class Target;
class SMLoc; class SMLoc;
class AsmToken; class AsmToken;
class MCParsedAsmOperand; class MCParsedAsmOperand;
@ -26,23 +25,19 @@ class TargetAsmParser : public MCAsmParserExtension {
TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT
void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT
protected: // Can only create subclasses. protected: // Can only create subclasses.
TargetAsmParser(const Target &); TargetAsmParser();
/// The Target that this machine was created for. /// AvailableFeatures - The current set of available features.
const Target &TheTarget;
/// The current set of available features.
unsigned AvailableFeatures; unsigned AvailableFeatures;
public: public:
virtual ~TargetAsmParser(); virtual ~TargetAsmParser();
const Target &getTarget() const { return TheTarget; }
unsigned getAvailableFeatures() const { return AvailableFeatures; } unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
/// ParseInstruction - Parse one assembly instruction. /// ParseInstruction - Parse one assembly instruction.
/// ///

View File

@ -259,7 +259,7 @@ public:
/// getIntPtrType - Return an unsigned integer type that is the same size or /// getIntPtrType - Return an unsigned integer type that is the same size or
/// greater to the host pointer size. /// greater to the host pointer size.
/// ///
const IntegerType *getIntPtrType(LLVMContext &C) const; IntegerType *getIntPtrType(LLVMContext &C) const;
/// getIndexedOffset - return the offset from the beginning of the type for /// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr. /// the specified indices. This is used to implement getelementptr.
@ -272,12 +272,6 @@ public:
/// information is lazily cached. /// information is lazily cached.
const StructLayout *getStructLayout(const StructType *Ty) const; const StructLayout *getStructLayout(const StructType *Ty) const;
/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
/// objects. If a TargetData object is alive when types are being refined and
/// removed, this method must be called whenever a StructType is removed to
/// avoid a dangling pointer in this cache.
void InvalidateStructLayoutInfo(const StructType *Ty) const;
/// getPreferredAlignment - Return the preferred alignment of the specified /// getPreferredAlignment - Return the preferred alignment of the specified
/// global. This includes an explicitly requested alignment (if the global /// global. This includes an explicitly requested alignment (if the global
/// has one). /// has one).

Some files were not shown because too many files have changed in this diff Show More