Upgrade our copy of llvm/clang to r135360, from upstream's trunk.
This commit is contained in:
commit
17a519f92f
@ -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 )
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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> > {
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -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
|
|
53
contrib/llvm/include/llvm/Analysis/BlockFrequency.h
Normal file
53
contrib/llvm/include/llvm/Analysis/BlockFrequency.h
Normal 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
|
349
contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h
Normal file
349
contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h
Normal 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
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
53
contrib/llvm/include/llvm/CodeGen/MachineBlockFrequency.h
Normal file
53
contrib/llvm/include/llvm/CodeGen/MachineBlockFrequency.h
Normal 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
|
@ -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
|
@ -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);
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
@ -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.
|
||||||
|
@ -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 */
|
||||||
|
@ -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 ©) {}
|
|
||||||
|
|
||||||
/// 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
|
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class InstrItineraryData;
|
class InstrItineraryData;
|
||||||
class TargetInstrDesc;
|
|
||||||
class ScheduleDAG;
|
class ScheduleDAG;
|
||||||
class SUnit;
|
class SUnit;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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; }
|
||||||
|
@ -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.
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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&);
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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]>;
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
51
contrib/llvm/include/llvm/MC/MCInstrInfo.h
Normal file
51
contrib/llvm/include/llvm/MC/MCInstrInfo.h
Normal 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
|
@ -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>
|
||||||
|
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
129
contrib/llvm/include/llvm/MC/MCRegisterInfo.h
Normal file
129
contrib/llvm/include/llvm/MC/MCRegisterInfo.h
Normal 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
|
@ -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,
|
||||||
|
79
contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
Normal file
79
contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
Normal 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
|
@ -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
|
@ -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
|
||||||
|
67
contrib/llvm/include/llvm/Object/Binary.h
Normal file
67
contrib/llvm/include/llvm/Object/Binary.h
Normal 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
|
117
contrib/llvm/include/llvm/Object/COFF.h
Normal file
117
contrib/llvm/include/llvm/Object/COFF.h
Normal 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
|
50
contrib/llvm/include/llvm/Object/Error.h
Normal file
50
contrib/llvm/include/llvm/Object/Error.h
Normal 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
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 <>
|
||||||
|
@ -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.
|
||||||
|
@ -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"
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user