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;
|
||||
|
||||
/**
|
||||
* 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 LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
||||
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
|
||||
@ -206,7 +199,6 @@ typedef enum {
|
||||
LLVMStructTypeKind, /**< Structures */
|
||||
LLVMArrayTypeKind, /**< Arrays */
|
||||
LLVMPointerTypeKind, /**< Pointers */
|
||||
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
|
||||
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
|
||||
LLVMMetadataTypeKind, /**< Metadata */
|
||||
LLVMX86_MMXTypeKind /**< X86 MMX */
|
||||
@ -320,12 +312,6 @@ void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple);
|
||||
const char *LLVMGetTarget(LLVMModuleRef M);
|
||||
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. */
|
||||
void LLVMDumpModule(LLVMModuleRef M);
|
||||
|
||||
@ -401,9 +387,16 @@ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
|
||||
unsigned ElementCount, LLVMBool Packed);
|
||||
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
|
||||
LLVMBool Packed);
|
||||
LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
|
||||
void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
|
||||
unsigned ElementCount, LLVMBool Packed);
|
||||
|
||||
unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
|
||||
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
|
||||
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
|
||||
LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy);
|
||||
|
||||
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
|
||||
|
||||
/* Operations on array, pointer, and vector types (sequence types) */
|
||||
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
|
||||
@ -418,21 +411,12 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
|
||||
/* Operations on other types */
|
||||
LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C);
|
||||
LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
|
||||
LLVMTypeRef LLVMOpaqueTypeInContext(LLVMContextRef C);
|
||||
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
|
||||
|
||||
LLVMTypeRef LLVMVoidType(void);
|
||||
LLVMTypeRef LLVMLabelType(void);
|
||||
LLVMTypeRef LLVMOpaqueType(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 ------------------------------------------------------------===*/
|
||||
|
||||
/* 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 LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
|
||||
LLVMBool Packed);
|
||||
LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy,
|
||||
LLVMValueRef *ConstantVals,
|
||||
unsigned Count);
|
||||
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
|
||||
|
||||
/* Constant expressions */
|
||||
@ -1117,7 +1104,6 @@ namespace llvm {
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )
|
||||
|
@ -41,6 +41,11 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef;
|
||||
#include "llvm/Config/Targets.def"
|
||||
#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
|
||||
it wants access to all available targets that LLVM is configured to
|
||||
support. */
|
||||
@ -67,6 +72,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
|
||||
#ifdef LLVM_NATIVE_TARGET
|
||||
LLVM_NATIVE_TARGETINFO();
|
||||
LLVM_NATIVE_TARGET();
|
||||
LLVM_NATIVE_MCASMINFO();
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
@ -141,12 +147,6 @@ unsigned LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef StructTy,
|
||||
unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
|
||||
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.
|
||||
See the destructor llvm::TargetData::~TargetData. */
|
||||
void LLVMDisposeTargetData(LLVMTargetDataRef);
|
||||
|
@ -30,9 +30,6 @@ void LLVMAddConstantMergePass(LLVMPassManagerRef PM);
|
||||
/** See llvm::createDeadArgEliminationPass function. */
|
||||
void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createDeadTypeEliminationPass function. */
|
||||
void LLVMAddDeadTypeEliminationPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createFunctionAttrsPass function. */
|
||||
void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);
|
||||
|
||||
|
@ -109,6 +109,7 @@ namespace llvm {
|
||||
typedef signed short exponent_t;
|
||||
|
||||
struct fltSemantics;
|
||||
class APSInt;
|
||||
class StringRef;
|
||||
|
||||
/* 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 convertToInteger(integerPart *, unsigned int, bool,
|
||||
roundingMode, bool *) const;
|
||||
opStatus convertToInteger(APSInt&, roundingMode, bool *) const;
|
||||
opStatus convertFromAPInt(const APInt &,
|
||||
bool, roundingMode);
|
||||
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
|
||||
|
@ -1241,18 +1241,19 @@ class APInt {
|
||||
|
||||
/// toString - Converts an APInt to a string and append it to Str. Str is
|
||||
/// 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
|
||||
/// radix given. The radix can be 2, 8, 10 or 16.
|
||||
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
|
||||
/// radix given. The radix can be 2, 8, 10 or 16.
|
||||
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
|
||||
|
@ -39,7 +39,7 @@ namespace llvm {
|
||||
const T *Data;
|
||||
|
||||
/// The number of elements.
|
||||
size_t Length;
|
||||
size_type Length;
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
@ -56,6 +56,10 @@ namespace llvm {
|
||||
/*implicit*/ ArrayRef(const T *data, size_t 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.
|
||||
/*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
|
||||
: Data(Vec.data()), Length(Vec.size()) {}
|
||||
@ -96,6 +100,16 @@ namespace llvm {
|
||||
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.
|
||||
ArrayRef<T> slice(unsigned N) {
|
||||
assert(N <= size() && "Invalid specifier");
|
||||
@ -124,9 +138,31 @@ namespace llvm {
|
||||
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.
|
||||
template <typename T> struct isPodLike;
|
||||
template <typename T> struct isPodLike<ArrayRef<T> > {
|
||||
|
@ -103,6 +103,14 @@ class ImmutableList {
|
||||
/// isEmpty - Returns true if the list is empty.
|
||||
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
|
||||
/// 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
|
||||
|
@ -90,7 +90,7 @@ class PackedVector : public PackedVectorBase<T, BitNum,
|
||||
Vec.setValue(Vec.Bits, Idx, val);
|
||||
return *this;
|
||||
}
|
||||
operator T() {
|
||||
operator T() const {
|
||||
return Vec.getValue(Vec.Bits, Idx);
|
||||
}
|
||||
};
|
||||
|
@ -410,7 +410,14 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||
this->setEnd(this->end()+1);
|
||||
// Push everything else over.
|
||||
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;
|
||||
}
|
||||
size_t EltNo = I-this->begin();
|
||||
|
@ -140,7 +140,7 @@ class StringMapEntry : public StringMapEntryBase {
|
||||
/// StringMapEntry object.
|
||||
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
|
||||
/// construct the value.
|
||||
@ -307,7 +307,7 @@ class StringMap : public StringMapImpl {
|
||||
return ValueTy();
|
||||
}
|
||||
|
||||
ValueTy& operator[](StringRef Key) {
|
||||
ValueTy &operator[](StringRef Key) {
|
||||
return GetOrCreateValue(Key).getValue();
|
||||
}
|
||||
|
||||
@ -355,8 +355,7 @@ class StringMap : public StringMapImpl {
|
||||
/// exists, return it. Otherwise, default construct a value, insert it, and
|
||||
/// return.
|
||||
template <typename InitTy>
|
||||
StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key,
|
||||
InitTy Val) {
|
||||
MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
|
||||
unsigned BucketNo = LookupBucketFor(Key);
|
||||
ItemBucket &Bucket = TheTable[BucketNo];
|
||||
if (Bucket.Item && Bucket.Item != getTombstoneVal())
|
||||
@ -378,22 +377,10 @@ class StringMap : public StringMapImpl {
|
||||
return *NewItem;
|
||||
}
|
||||
|
||||
StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key) {
|
||||
MapEntryTy &GetOrCreateValue(StringRef Key) {
|
||||
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
|
||||
/// erase it. This aborts if the key is not in the map.
|
||||
void remove(MapEntryTy *KeyValue) {
|
||||
|
@ -95,7 +95,8 @@ class Triple {
|
||||
Solaris,
|
||||
Win32,
|
||||
Haiku,
|
||||
Minix
|
||||
Minix,
|
||||
RTEMS
|
||||
};
|
||||
enum EnvironmentType {
|
||||
UnknownEnvironment,
|
||||
@ -237,19 +238,10 @@ class Triple {
|
||||
/// specialized because it is a common query.
|
||||
unsigned getOSMajorVersion() const {
|
||||
unsigned Maj, Min, Micro;
|
||||
getDarwinNumber(Maj, Min, Micro);
|
||||
getOSVersion(Maj, Min, Micro);
|
||||
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
|
||||
/// numbers included in the target triple.
|
||||
bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
|
||||
@ -275,7 +267,7 @@ class Triple {
|
||||
|
||||
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
|
||||
bool isOSDarwin() const {
|
||||
return isMacOSX() ||getOS() == Triple::IOS;
|
||||
return isMacOSX() || getOS() == Triple::IOS;
|
||||
}
|
||||
|
||||
/// isOSWindows - Is this a "Windows" OS.
|
||||
@ -288,7 +280,7 @@ class Triple {
|
||||
/// compatibility, which handles supporting skewed version numbering schemes
|
||||
/// used by the "darwin" triples.
|
||||
unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
|
||||
unsigned Micro = 0) const {
|
||||
unsigned Micro = 0) const {
|
||||
assert(isMacOSX() && "Not an OS X triple!");
|
||||
|
||||
// If this is OS X, expect a sane version number.
|
||||
@ -299,7 +291,7 @@ class Triple {
|
||||
assert(Major == 10 && "Unexpected major version");
|
||||
return isOSVersionLT(Minor + 4, Micro, 0);
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
/// @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
|
||||
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -25,6 +26,11 @@ class raw_ostream;
|
||||
class BranchProbabilityInfo : public FunctionPass {
|
||||
|
||||
// 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;
|
||||
|
||||
typedef std::pair<BasicBlock *, BasicBlock *> Edge;
|
||||
@ -41,10 +47,7 @@ class BranchProbabilityInfo : public FunctionPass {
|
||||
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<LoopInfo>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
|
@ -135,6 +135,7 @@ namespace llvm {
|
||||
unsigned Flags);
|
||||
|
||||
/// createMemberType - Create debugging information entry for a member.
|
||||
/// @param Scope Member scope.
|
||||
/// @param Name Member name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNo Line number.
|
||||
@ -143,7 +144,7 @@ namespace llvm {
|
||||
/// @param OffsetInBits Member offset.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Ty Parent type.
|
||||
DIType createMemberType(StringRef Name, DIFile File,
|
||||
DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
|
||||
unsigned LineNo, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned Flags, DIType Ty);
|
||||
|
@ -37,8 +37,8 @@ class TargetData;
|
||||
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
friend class IVUsers;
|
||||
public:
|
||||
IVStrideUse(IVUsers *P, Instruction* U, Value *O, Value *PN)
|
||||
: CallbackVH(U), Parent(P), OperandValToReplace(O), Phi(PN) {
|
||||
IVStrideUse(IVUsers *P, Instruction* U, Value *O)
|
||||
: CallbackVH(U), Parent(P), OperandValToReplace(O) {
|
||||
}
|
||||
|
||||
/// getUser - Return the user instruction for this use.
|
||||
@ -51,11 +51,6 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
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
|
||||
/// instruction that this IVStrideUse is representing.
|
||||
Value *getOperandValToReplace() const {
|
||||
@ -86,9 +81,6 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
/// that this IVStrideUse is representing.
|
||||
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
|
||||
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
|
||||
PostIncLoopSet PostIncLoops;
|
||||
@ -151,9 +143,9 @@ class IVUsers : public LoopPass {
|
||||
/// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
|
||||
/// reducible SCEV, recursively add its users to the IVUsesByStride set and
|
||||
/// 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
|
||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||
|
@ -90,18 +90,27 @@ namespace llvm {
|
||||
/// get methods: These are static ctor methods for creating various
|
||||
/// MemDepResult kinds.
|
||||
static MemDepResult getDef(Instruction *Inst) {
|
||||
assert(Inst && "Def requires inst");
|
||||
return MemDepResult(PairTy(Inst, Def));
|
||||
}
|
||||
static MemDepResult getClobber(Instruction *Inst) {
|
||||
assert(Inst && "Clobber requires inst");
|
||||
return MemDepResult(PairTy(Inst, Clobber));
|
||||
}
|
||||
static MemDepResult getNonLocal() {
|
||||
return MemDepResult(PairTy(0, NonLocal));
|
||||
}
|
||||
static MemDepResult getUnknown() {
|
||||
return MemDepResult(PairTy(0, Clobber));
|
||||
}
|
||||
|
||||
/// isClobber - Return true if this MemDepResult represents a query that is
|
||||
/// 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
|
||||
/// a instruction definition dependency.
|
||||
|
@ -86,6 +86,13 @@ namespace llvm {
|
||||
//
|
||||
ImmutablePass *createTypeBasedAliasAnalysisPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
|
||||
// alias analysis.
|
||||
//
|
||||
ImmutablePass *createObjCARCAliasAnalysisPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createProfileLoaderPass - This pass loads information from a profile dump
|
||||
|
@ -30,6 +30,10 @@ namespace llvm {
|
||||
/// memory.
|
||||
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
|
||||
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> >
|
||||
InsertedExpressions;
|
||||
std::set<AssertingVH<Value> > InsertedValues;
|
||||
@ -67,9 +71,9 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
|
||||
explicit SCEVExpander(ScalarEvolution &se)
|
||||
: SE(se), IVIncInsertLoop(0), CanonicalMode(true),
|
||||
Builder(se.getContext(), TargetFolder(se.TD)) {}
|
||||
explicit SCEVExpander(ScalarEvolution &se, const char *name)
|
||||
: SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
|
||||
CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {}
|
||||
|
||||
/// clear - Erase the contents of the InsertedExpressions map so that users
|
||||
/// trying to expand the same expression into multiple BasicBlocks or
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
|
||||
#define LLVM_ANALYSIS_VALUETRACKING_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
@ -108,18 +109,9 @@ namespace llvm {
|
||||
/// If InsertBefore is not null, this function will duplicate (modified)
|
||||
/// insertvalues when a part of a nested struct is extracted.
|
||||
Value *FindInsertedValue(Value *V,
|
||||
const unsigned *idx_begin,
|
||||
const unsigned *idx_end,
|
||||
ArrayRef<unsigned> idx_range,
|
||||
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
|
||||
/// it can be expressed as a base pointer plus a constant offset. Return the
|
||||
/// base and offset to the caller.
|
||||
@ -158,6 +150,10 @@ namespace llvm {
|
||||
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
|
||||
|
||||
#endif
|
||||
|
@ -17,52 +17,12 @@
|
||||
#ifndef LLVM_ASSEMBLY_WRITER_H
|
||||
#define LLVM_ASSEMBLY_WRITER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Type;
|
||||
class Module;
|
||||
class Value;
|
||||
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
|
||||
// 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
|
||||
const Attributes UWTable = 1<<30; ///< Function must be in a unwind
|
||||
///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
|
||||
/// 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 |
|
||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
|
||||
Hotpatch | UWTable;
|
||||
Hotpatch | UWTable | NonLazyBind;
|
||||
|
||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||
const Attributes VarArgsIncompatible = StructRet;
|
||||
|
@ -110,7 +110,7 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
Function *getParent() { return Parent; }
|
||||
|
||||
/// 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).
|
||||
User *use_back() { return cast<User>(*use_begin());}
|
||||
const User *use_back() const { return cast<User>(*use_begin());}
|
||||
@ -138,6 +138,12 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
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
|
||||
/// function, but does not delete it.
|
||||
///
|
||||
@ -248,6 +254,10 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
/// other than direct branches, switches, etc. to it.
|
||||
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:
|
||||
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
|
||||
/// objects using it. This is almost always 0, sometimes one, possibly but
|
||||
|
@ -194,6 +194,7 @@ class BitstreamCursor {
|
||||
CurAbbrevs[i]->addRef();
|
||||
|
||||
// Copy block scope and bump ref counts.
|
||||
BlockScope = RHS.BlockScope;
|
||||
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
|
||||
S != e; ++S) {
|
||||
std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
|
||||
@ -375,10 +376,12 @@ class BitstreamCursor {
|
||||
|
||||
// Check that the block wasn't partially defined, and that the offset isn't
|
||||
// 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;
|
||||
|
||||
NextChar += NumWords*4;
|
||||
NextChar = SkipTo;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -29,13 +29,23 @@ namespace bitc {
|
||||
|
||||
// Module sub-block id's.
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
enum TypeCodes {
|
||||
TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
|
||||
TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
|
||||
|
||||
// Type Codes
|
||||
TYPE_CODE_VOID = 2, // VOID
|
||||
TYPE_CODE_FLOAT = 3, // FLOAT
|
||||
TYPE_CODE_DOUBLE = 4, // DOUBLE
|
||||
TYPE_CODE_LABEL = 5, // LABEL
|
||||
TYPE_CODE_OPAQUE = 6, // OPAQUE
|
||||
TYPE_CODE_INTEGER = 7, // INTEGER: [width]
|
||||
TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
|
||||
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]
|
||||
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
|
||||
TYPE_CODE_VOID = 2, // VOID
|
||||
TYPE_CODE_FLOAT = 3, // FLOAT
|
||||
TYPE_CODE_DOUBLE = 4, // DOUBLE
|
||||
TYPE_CODE_LABEL = 5, // LABEL
|
||||
TYPE_CODE_OPAQUE = 6, // OPAQUE
|
||||
TYPE_CODE_INTEGER = 7, // INTEGER: [width]
|
||||
TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
|
||||
TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N]
|
||||
|
||||
// FIXME: This is the encoding used for structs in LLVM 2.9 and earlier.
|
||||
// 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
|
||||
// a late addition, and putting them in the right place breaks
|
||||
// binary compatibility.
|
||||
TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE
|
||||
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
|
||||
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
|
||||
TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE
|
||||
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
|
||||
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).
|
||||
@ -112,20 +129,16 @@ namespace bitc {
|
||||
|
||||
enum MetadataCodes {
|
||||
METADATA_STRING = 1, // MDSTRING: [values]
|
||||
// FIXME: Remove NODE in favor of NODE2 in LLVM 3.0
|
||||
METADATA_NODE = 2, // NODE with potentially invalid metadata
|
||||
// FIXME: Remove FN_NODE in favor of FN_NODE2 in LLVM 3.0
|
||||
METADATA_FN_NODE = 3, // FN_NODE with potentially invalid metadata
|
||||
// 2 is unused.
|
||||
// 3 is unused.
|
||||
METADATA_NAME = 4, // STRING: [values]
|
||||
// FIXME: Remove NAMED_NODE in favor of NAMED_NODE2 in LLVM 3.0
|
||||
METADATA_NAMED_NODE = 5, // NAMED_NODE with potentially invalid metadata
|
||||
// 5 is unused.
|
||||
METADATA_KIND = 6, // [n x [id, name]]
|
||||
// FIXME: Remove ATTACHMENT in favor of ATTACHMENT2 in LLVM 3.0
|
||||
METADATA_ATTACHMENT = 7, // ATTACHMENT with potentially invalid metadata
|
||||
METADATA_NODE2 = 8, // NODE2: [n x (type num, value num)]
|
||||
METADATA_FN_NODE2 = 9, // FN_NODE2: [n x (type num, value num)]
|
||||
METADATA_NAMED_NODE2 = 10, // NAMED_NODE2: [n x mdnodes]
|
||||
METADATA_ATTACHMENT2 = 11 // [m x [value, [n x [id, mdnode]]]
|
||||
// 7 is unused.
|
||||
METADATA_NODE = 8, // NODE: [n x (type num, value num)]
|
||||
METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)]
|
||||
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
|
||||
METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]]
|
||||
};
|
||||
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
|
||||
// constant and maintains an implicit current type value.
|
||||
@ -227,21 +240,18 @@ namespace bitc {
|
||||
FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
|
||||
|
||||
FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
|
||||
FUNC_CODE_INST_MALLOC = 17, // MALLOC: [instty, op, align]
|
||||
FUNC_CODE_INST_FREE = 18, // FREE: [opty, op]
|
||||
// 17 is unused.
|
||||
// 18 is unused.
|
||||
FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
|
||||
FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
|
||||
// FIXME: Remove STORE in favor of STORE2 in LLVM 3.0
|
||||
FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol]
|
||||
// FIXME: Remove CALL in favor of CALL2 in LLVM 3.0
|
||||
FUNC_CODE_INST_CALL = 22, // CALL with potentially invalid metadata
|
||||
// 21 is unused.
|
||||
// 22 is unused.
|
||||
FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty]
|
||||
// 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
|
||||
// spaces) is retained.
|
||||
FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol]
|
||||
// FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0
|
||||
FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n]
|
||||
FUNC_CODE_INST_STORE = 24, // STORE: [ptrty,ptr,val, align, vol]
|
||||
// 25 is unused.
|
||||
FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [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
|
||||
@ -251,14 +261,12 @@ namespace bitc {
|
||||
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_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
|
||||
|
||||
// FIXME: Remove DEBUG_LOC in favor of DEBUG_LOC2 in LLVM 3.0
|
||||
FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC with potentially invalid metadata
|
||||
// 32 is unused.
|
||||
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 llvm namespace
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
@ -37,6 +38,12 @@ unsigned ComputeLinearIndex(const Type *Ty,
|
||||
const unsigned *IndicesEnd,
|
||||
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
|
||||
/// EVTs that represent all the individual underlying
|
||||
/// non-aggregate types that comprise it.
|
||||
|
@ -465,8 +465,8 @@ namespace llvm {
|
||||
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||
const MachineBasicBlock *MBB,
|
||||
unsigned uid) const;
|
||||
void EmitLLVMUsedList(Constant *List);
|
||||
void EmitXXStructorList(Constant *List);
|
||||
void EmitLLVMUsedList(const Constant *List);
|
||||
void EmitXXStructorList(const Constant *List);
|
||||
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
|
||||
};
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#ifndef NDEBUG
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#endif
|
||||
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
@ -57,7 +58,7 @@ class FunctionLoweringInfo {
|
||||
const Function *Fn;
|
||||
MachineFunction *MF;
|
||||
MachineRegisterInfo *RegInfo;
|
||||
|
||||
BranchProbabilityInfo *BPI;
|
||||
/// CanLowerReturn - true iff the function's return value can be lowered to
|
||||
/// registers.
|
||||
bool CanLowerReturn;
|
||||
|
@ -232,7 +232,7 @@ namespace ISD {
|
||||
SMULO, UMULO,
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// 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,
|
||||
|
||||
// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
|
||||
|
@ -39,8 +39,6 @@ namespace {
|
||||
(void) llvm::createGreedyRegisterAllocator();
|
||||
(void) llvm::createDefaultPBQPRegisterAllocator();
|
||||
|
||||
(void) llvm::createSimpleRegisterCoalescer();
|
||||
|
||||
llvm::linkOcamlGC();
|
||||
llvm::linkShadowStackGC();
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
@ -27,6 +28,7 @@ class MCSymbol;
|
||||
class SlotIndexes;
|
||||
class StringRef;
|
||||
class raw_ostream;
|
||||
class MachineBranchProbabilityInfo;
|
||||
|
||||
template <>
|
||||
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
|
||||
@ -63,12 +65,19 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
const BasicBlock *BB;
|
||||
int Number;
|
||||
MachineFunction *xParent;
|
||||
|
||||
|
||||
/// Predecessors/Successors - Keep track of the predecessor / successor
|
||||
/// basicblocks.
|
||||
std::vector<MachineBasicBlock *> Predecessors;
|
||||
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
|
||||
/// the basicblock.
|
||||
std::vector<unsigned> LiveIns;
|
||||
@ -244,11 +253,13 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
void updateTerminator();
|
||||
|
||||
// Machine-CFG mutators
|
||||
|
||||
|
||||
/// 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
|
||||
/// MachineBasicBlock. The Predecessors list of succ is automatically updated.
|
||||
@ -260,7 +271,12 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// updated. Return the iterator to the element after the one removed.
|
||||
///
|
||||
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
|
||||
/// machine basic block (i.e., copies all the successors fromMBB and
|
||||
/// remove all the successors from fromMBB).
|
||||
@ -396,8 +412,22 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// getSymbol - Return the MCSymbol for this basic block.
|
||||
///
|
||||
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>;
|
||||
|
||||
// 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 @@ class MachineFunction {
|
||||
/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
|
||||
/// of `new MachineInstr'.
|
||||
///
|
||||
MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID,
|
||||
MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
|
||||
DebugLoc DL,
|
||||
bool NoImp = false);
|
||||
|
||||
|
@ -17,11 +17,12 @@
|
||||
#define LLVM_CODEGEN_MACHINEINSTR_H
|
||||
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/Target/TargetInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include <vector>
|
||||
@ -30,7 +31,6 @@ namespace llvm {
|
||||
|
||||
template <typename T> class SmallVectorImpl;
|
||||
class AliasAnalysis;
|
||||
class TargetInstrDesc;
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterInfo;
|
||||
class MachineFunction;
|
||||
@ -57,7 +57,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
// function frame setup code.
|
||||
};
|
||||
private:
|
||||
const TargetInstrDesc *TID; // Instruction descriptor.
|
||||
const MCInstrDesc *MCID; // Instruction descriptor.
|
||||
uint16_t NumImplicitOps; // Number of implicit operands (which
|
||||
// are determined at construction time).
|
||||
|
||||
@ -94,7 +94,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
MachineInstr(MachineFunction &, const MachineInstr &);
|
||||
|
||||
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
|
||||
/// TID NULL and no operands.
|
||||
/// MCID NULL and no operands.
|
||||
MachineInstr();
|
||||
|
||||
// The next two constructors have DebugLoc and non-DebugLoc versions;
|
||||
@ -103,25 +103,25 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
|
||||
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
|
||||
/// implicit operands. It reserves space for the number of operands specified
|
||||
/// by the TargetInstrDesc. The version with a DebugLoc should be preferred.
|
||||
explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false);
|
||||
/// by the MCInstrDesc. The version with a DebugLoc should be preferred.
|
||||
explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false);
|
||||
|
||||
/// 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
|
||||
/// 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
|
||||
/// implicit operands. It reserves space for number of operands specified by
|
||||
/// TargetInstrDesc. An explicit DebugLoc is supplied.
|
||||
explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl,
|
||||
/// MCInstrDesc. An explicit DebugLoc is supplied.
|
||||
explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
|
||||
bool NoImp = false);
|
||||
|
||||
/// 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
|
||||
/// block.
|
||||
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
|
||||
const TargetInstrDesc &TID);
|
||||
const MCInstrDesc &MCID);
|
||||
|
||||
~MachineInstr();
|
||||
|
||||
@ -181,13 +181,22 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
///
|
||||
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
|
||||
/// MachineInstr.
|
||||
const TargetInstrDesc &getDesc() const { return *TID; }
|
||||
const MCInstrDesc &getDesc() const { return *MCID; }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
@ -279,6 +288,9 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
bool isCopy() const {
|
||||
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.
|
||||
/// This does not include native copy instructions.
|
||||
@ -464,8 +476,8 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
|
||||
/// hasUnmodeledSideEffects - Return true if this instruction has side
|
||||
/// effects that are not modeled by mayLoad / mayStore, etc.
|
||||
/// For all instructions, the property is encoded in TargetInstrDesc::Flags
|
||||
/// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is
|
||||
/// For all instructions, the property is encoded in MCInstrDesc::Flags
|
||||
/// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is
|
||||
/// INLINEASM instruction, in which case the side effect property is encoded
|
||||
/// in one of its operands (see InlineAsm::Extra_HasSideEffect).
|
||||
///
|
||||
@ -497,7 +509,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
/// setDesc - Replace the instruction descriptor (thus opcode) of
|
||||
/// 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.
|
||||
/// Avoid using this, the constructor argument is preferable.
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetInstrDesc;
|
||||
class MCInstrDesc;
|
||||
class MDNode;
|
||||
|
||||
namespace RegState {
|
||||
@ -77,6 +77,11 @@ class MachineInstrBuilder {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
|
||||
MI->addOperand(MachineOperand::CreateCImm(Val));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
|
||||
MI->addOperand(MachineOperand::CreateFPImm(Val));
|
||||
return *this;
|
||||
@ -175,8 +180,8 @@ class MachineInstrBuilder {
|
||||
///
|
||||
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID) {
|
||||
return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
|
||||
const MCInstrDesc &MCID) {
|
||||
return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
|
||||
}
|
||||
|
||||
/// 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,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID,
|
||||
const MCInstrDesc &MCID,
|
||||
unsigned DestReg) {
|
||||
return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
|
||||
return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
|
||||
.addReg(DestReg, RegState::Define);
|
||||
}
|
||||
|
||||
@ -197,9 +202,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
|
||||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID,
|
||||
const MCInstrDesc &MCID,
|
||||
unsigned DestReg) {
|
||||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
|
||||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
|
||||
BB.insert(I, MI);
|
||||
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
|
||||
}
|
||||
@ -211,8 +216,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
|
||||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID) {
|
||||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
|
||||
const MCInstrDesc &MCID) {
|
||||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
|
||||
BB.insert(I, MI);
|
||||
return MachineInstrBuilder(MI);
|
||||
}
|
||||
@ -223,8 +228,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
|
||||
///
|
||||
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID) {
|
||||
return BuildMI(*BB, BB->end(), DL, TID);
|
||||
const MCInstrDesc &MCID) {
|
||||
return BuildMI(*BB, BB->end(), DL, MCID);
|
||||
}
|
||||
|
||||
/// BuildMI - This version of the builder inserts the newly-built
|
||||
@ -233,9 +238,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
|
||||
///
|
||||
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
|
||||
DebugLoc DL,
|
||||
const TargetInstrDesc &TID,
|
||||
const MCInstrDesc &MCID,
|
||||
unsigned DestReg) {
|
||||
return BuildMI(*BB, BB->end(), DL, TID, DestReg);
|
||||
return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
|
||||
}
|
||||
|
||||
inline unsigned getDefRegState(bool B) {
|
||||
|
@ -21,6 +21,7 @@ namespace llvm {
|
||||
|
||||
class BlockAddress;
|
||||
class ConstantFP;
|
||||
class ConstantInt;
|
||||
class GlobalValue;
|
||||
class MachineBasicBlock;
|
||||
class MachineInstr;
|
||||
@ -38,6 +39,7 @@ class MachineOperand {
|
||||
enum MachineOperandType {
|
||||
MO_Register, ///< Register operand.
|
||||
MO_Immediate, ///< Immediate operand
|
||||
MO_CImmediate, ///< Immediate >64bit operand
|
||||
MO_FPImmediate, ///< Floating-point immediate operand
|
||||
MO_MachineBasicBlock, ///< MachineBasicBlock reference
|
||||
MO_FrameIndex, ///< Abstract Stack Frame Index
|
||||
@ -111,6 +113,7 @@ class MachineOperand {
|
||||
union {
|
||||
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
|
||||
const ConstantFP *CFP; // For MO_FPImmediate.
|
||||
const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
|
||||
int64_t ImmVal; // For MO_Immediate.
|
||||
const MDNode *MD; // For MO_Metadata.
|
||||
MCSymbol *Sym; // For MO_MCSymbol
|
||||
@ -173,6 +176,8 @@ class MachineOperand {
|
||||
bool isReg() const { return OpKind == MO_Register; }
|
||||
/// isImm - Tests if this is a MO_Immediate operand.
|
||||
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.
|
||||
bool isFPImm() const { return OpKind == MO_FPImmediate; }
|
||||
/// isMBB - Tests if this is a MO_MachineBasicBlock operand.
|
||||
@ -333,6 +338,11 @@ class MachineOperand {
|
||||
return Contents.ImmVal;
|
||||
}
|
||||
|
||||
const ConstantInt *getCImm() const {
|
||||
assert(isCImm() && "Wrong MachineOperand accessor");
|
||||
return Contents.CI;
|
||||
}
|
||||
|
||||
const ConstantFP *getFPImm() const {
|
||||
assert(isFPImm() && "Wrong MachineOperand accessor");
|
||||
return Contents.CFP;
|
||||
@ -440,6 +450,12 @@ class MachineOperand {
|
||||
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) {
|
||||
MachineOperand Op(MachineOperand::MO_FPImmediate);
|
||||
Op.Contents.CFP = CFP;
|
||||
|
@ -32,11 +32,6 @@ class MachineRegisterInfo {
|
||||
IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
|
||||
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
|
||||
/// registers. For each virtual register, it keeps a register and hint type
|
||||
/// pair making up the allocation hint. Hint type is target specific except
|
||||
@ -216,13 +211,6 @@ class MachineRegisterInfo {
|
||||
///
|
||||
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
|
||||
/// specified virtual register.
|
||||
void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
|
||||
@ -237,6 +225,14 @@ class MachineRegisterInfo {
|
||||
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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -73,16 +73,9 @@ namespace llvm {
|
||||
/// This pass is still in development
|
||||
extern char &StrongPHIEliminationID;
|
||||
|
||||
extern char &PreAllocSplittingID;
|
||||
|
||||
/// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
|
||||
extern char &LiveStacksID;
|
||||
|
||||
/// SimpleRegisterCoalescing pass. Aggressively coalesces every register
|
||||
/// copy it can.
|
||||
///
|
||||
extern char &SimpleRegisterCoalescingID;
|
||||
|
||||
/// TwoAddressInstruction pass - This pass reduces two-address instructions to
|
||||
/// use two operands. This destroys SSA information but it is desired by
|
||||
/// register allocators.
|
||||
@ -132,10 +125,10 @@ namespace llvm {
|
||||
///
|
||||
FunctionPass *createDefaultPBQPRegisterAllocator();
|
||||
|
||||
/// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
|
||||
/// RegisterCoalescer Pass - Coalesce all copies possible. Can run
|
||||
/// independently of the register allocator.
|
||||
///
|
||||
RegisterCoalescer *createSimpleRegisterCoalescer();
|
||||
RegisterCoalescer *createRegisterCoalescer();
|
||||
|
||||
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
|
||||
/// and eliminates abstract frame references.
|
||||
|
@ -161,7 +161,8 @@ namespace llvm {
|
||||
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 */
|
||||
|
@ -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
|
||||
/// the backend can emit. The various long double types cannot be merged,
|
||||
/// because 80-bit library functions use "xf" and 128-bit use "tf".
|
||||
///
|
||||
///
|
||||
/// When adding PPCF128 functions here, note that their names generally need
|
||||
/// to be overridden for Darwin with the xxx$LDBL128 form. See
|
||||
/// PPCISelLowering.cpp.
|
||||
@ -46,6 +46,9 @@ namespace RTLIB {
|
||||
MUL_I32,
|
||||
MUL_I64,
|
||||
MUL_I128,
|
||||
MULO_I32,
|
||||
MULO_I64,
|
||||
MULO_I128,
|
||||
SDIV_I8,
|
||||
SDIV_I16,
|
||||
SDIV_I32,
|
||||
@ -100,6 +103,10 @@ namespace RTLIB {
|
||||
REM_F64,
|
||||
REM_F80,
|
||||
REM_PPCF128,
|
||||
FMA_F32,
|
||||
FMA_F64,
|
||||
FMA_F80,
|
||||
FMA_PPCF128,
|
||||
POWI_F32,
|
||||
POWI_F64,
|
||||
POWI_F80,
|
||||
|
@ -34,7 +34,7 @@ namespace llvm {
|
||||
class ScheduleDAG;
|
||||
class SDNode;
|
||||
class TargetInstrInfo;
|
||||
class TargetInstrDesc;
|
||||
class MCInstrDesc;
|
||||
class TargetMachine;
|
||||
class TargetRegisterClass;
|
||||
template<class Graph> class GraphWriter;
|
||||
@ -497,13 +497,19 @@ namespace llvm {
|
||||
SUnit EntrySU; // Special node for the region entry.
|
||||
SUnit ExitSU; // Special node for the region exit.
|
||||
|
||||
#ifdef NDEBUG
|
||||
static const bool StressSched = false;
|
||||
#else
|
||||
bool StressSched;
|
||||
#endif
|
||||
|
||||
explicit ScheduleDAG(MachineFunction &mf);
|
||||
|
||||
virtual ~ScheduleDAG();
|
||||
|
||||
/// getInstrDesc - Return the TargetInstrDesc of this SUnit.
|
||||
/// getInstrDesc - Return the MCInstrDesc of this SUnit.
|
||||
/// 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();
|
||||
return getNodeDesc(SU->getNode());
|
||||
}
|
||||
@ -573,8 +579,8 @@ namespace llvm {
|
||||
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
|
||||
|
||||
private:
|
||||
// Return the TargetInstrDesc of this SDNode or NULL.
|
||||
const TargetInstrDesc *getNodeDesc(const SDNode *Node) const;
|
||||
// Return the MCInstrDesc of this SDNode or NULL.
|
||||
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
|
||||
};
|
||||
|
||||
class SUnitIterator : public std::iterator<std::forward_iterator_tag,
|
||||
|
@ -25,7 +25,6 @@
|
||||
namespace llvm {
|
||||
|
||||
class InstrItineraryData;
|
||||
class TargetInstrDesc;
|
||||
class ScheduleDAG;
|
||||
class SUnit;
|
||||
|
||||
|
@ -96,8 +96,12 @@ class SDDbgInfo {
|
||||
return DbgValues.empty() && ByvalParmDbgValues.empty();
|
||||
}
|
||||
|
||||
SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) {
|
||||
return DbgValMap[Node];
|
||||
ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *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;
|
||||
@ -898,7 +902,7 @@ class SelectionDAG {
|
||||
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
|
||||
|
||||
/// 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);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
@ -496,11 +497,29 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
///
|
||||
bool isOperandOf(SDNode *N) const;
|
||||
|
||||
/// isPredecessorOf - Return true if this node is a predecessor of N. This
|
||||
/// node is either an operand of N or it can be reached by recursively
|
||||
/// isPredecessorOf - Return true if this node is a predecessor of N.
|
||||
/// 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.
|
||||
/// NOTE: this is an expensive method. Use it carefully.
|
||||
bool isPredecessorOf(SDNode *N) const;
|
||||
/// NOTE: This is an expensive method. Use it carefully.
|
||||
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.
|
||||
///
|
||||
|
@ -140,6 +140,9 @@ namespace llvm {
|
||||
return lie.getPointer();
|
||||
}
|
||||
|
||||
/// Return true for a valid index.
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
/// Print this index to the given raw_ostream.
|
||||
void print(raw_ostream &os) const;
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
|
||||
const MCSection *MergeableConst8Section;
|
||||
const MCSection *MergeableConst16Section;
|
||||
public:
|
||||
TargetLoweringObjectFileELF() {}
|
||||
TargetLoweringObjectFileELF();
|
||||
~TargetLoweringObjectFileELF() {}
|
||||
|
||||
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
@ -131,7 +131,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
|
||||
const MCSection *LazySymbolPointerSection;
|
||||
const MCSection *NonLazySymbolPointerSection;
|
||||
public:
|
||||
TargetLoweringObjectFileMachO() {}
|
||||
TargetLoweringObjectFileMachO();
|
||||
~TargetLoweringObjectFileMachO() {}
|
||||
|
||||
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
@ -207,7 +207,7 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
|
||||
const MCSection *PDataSection;
|
||||
const MCSection *XDataSection;
|
||||
public:
|
||||
TargetLoweringObjectFileCOFF() {}
|
||||
TargetLoweringObjectFileCOFF();
|
||||
~TargetLoweringObjectFileCOFF() {}
|
||||
|
||||
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
@ -83,7 +83,11 @@ namespace llvm {
|
||||
|
||||
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.
|
||||
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
|
||||
|
@ -1,10 +1,10 @@
|
||||
//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
|
||||
//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 FlagVT : ValueType<0 , 34>; // Pre-RA sched glue
|
||||
def isVoid : ValueType<0 , 35>; // Produces no value
|
||||
def untyped: ValueType<8 , 36>; // Produces an untyped value
|
||||
|
||||
def MetadataVT: ValueType<0, 250>; // Metadata
|
||||
|
||||
|
@ -50,11 +50,11 @@ class Constant : public User {
|
||||
public:
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue.
|
||||
virtual bool isNullValue() const = 0;
|
||||
bool isNullValue() const;
|
||||
|
||||
/// isNegativeZeroValue - Return true if the value is what would be returned
|
||||
/// by getZeroValueForNegation.
|
||||
virtual bool isNegativeZeroValue() const { return isNullValue(); }
|
||||
bool isNegativeZeroValue() const;
|
||||
|
||||
/// canTrap - Return true if evaluation of this constant could trap. This is
|
||||
/// true for things like constant expressions that could divide by zero.
|
||||
|
@ -149,13 +149,7 @@ class ConstantInt : public Constant {
|
||||
static bool isValueValidForType(const Type *Ty, uint64_t V);
|
||||
static bool isValueValidForType(const Type *Ty, int64_t V);
|
||||
|
||||
/// This function will return true iff this constant represents the "null"
|
||||
/// 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;
|
||||
}
|
||||
bool isNegative() const { return Val.isNegative(); }
|
||||
|
||||
/// This is just a convenience method to make client code smaller for a
|
||||
/// common code. It also correctly performs the comparison without the
|
||||
@ -263,22 +257,14 @@ class ConstantFP : public Constant {
|
||||
|
||||
/// isValueValidForType - return true if Ty is big enough to represent V.
|
||||
static bool isValueValidForType(const Type *Ty, const APFloat &V);
|
||||
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();
|
||||
}
|
||||
inline const APFloat &getValueAPF() const { return Val; }
|
||||
|
||||
/// isZero - Return true if the value is positive or negative zero.
|
||||
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.
|
||||
bool isNaN() const { return Val.isNaN(); }
|
||||
|
||||
@ -324,10 +310,6 @@ class ConstantAggregateZero : public Constant {
|
||||
public:
|
||||
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();
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -350,9 +332,7 @@ class ConstantArray : public Constant {
|
||||
ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
|
||||
public:
|
||||
// ConstantArray accessors
|
||||
static Constant *get(const ArrayType *T, const std::vector<Constant*> &V);
|
||||
static Constant *get(const ArrayType *T, Constant *const *Vals,
|
||||
unsigned NumVals);
|
||||
static Constant *get(const ArrayType *T, ArrayRef<Constant*> V);
|
||||
|
||||
/// This method constructs a ConstantArray and initializes it with a text
|
||||
/// string. The default behavior (AddNull==true) causes a null terminator to
|
||||
@ -389,10 +369,11 @@ class ConstantArray : public Constant {
|
||||
///
|
||||
std::string getAsString() const;
|
||||
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue. This always returns false because zero arrays are always
|
||||
/// created as ConstantAggregateZero objects.
|
||||
virtual bool isNullValue() const { return false; }
|
||||
/// getAsCString - If this array is isCString(), then this method converts the
|
||||
/// array (without the trailing null byte) to an std::string and returns it.
|
||||
/// Otherwise, it asserts out.
|
||||
///
|
||||
std::string getAsCString() const;
|
||||
|
||||
virtual void destroyConstant();
|
||||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
|
||||
@ -422,14 +403,29 @@ class ConstantStruct : public Constant {
|
||||
ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
|
||||
public:
|
||||
// ConstantStruct accessors
|
||||
static Constant *get(const StructType *T, const std::vector<Constant*> &V);
|
||||
static Constant *get(LLVMContext &Context,
|
||||
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;
|
||||
static Constant *get(const StructType *T, ArrayRef<Constant*> V);
|
||||
static Constant *get(const StructType *T, ...) 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.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
@ -439,13 +435,6 @@ class ConstantStruct : public Constant {
|
||||
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 replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
|
||||
|
||||
@ -476,8 +465,6 @@ class ConstantVector : public Constant {
|
||||
public:
|
||||
// ConstantVector accessors
|
||||
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.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
@ -489,11 +476,6 @@ class ConstantVector : public Constant {
|
||||
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
|
||||
/// is set to all ones.
|
||||
/// @returns true iff this constant's emements are all set to all ones.
|
||||
@ -542,10 +524,6 @@ class ConstantPointerNull : public Constant {
|
||||
/// get() - Static factory methods - Return objects of the specified value
|
||||
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();
|
||||
|
||||
/// getType - Specialize the getType() method to always return an PointerType,
|
||||
@ -582,10 +560,6 @@ class BlockAddress : public Constant {
|
||||
Function *getFunction() const { return (Function*)Op<0>().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 replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
|
||||
|
||||
@ -623,35 +597,6 @@ class ConstantExpr : public Constant {
|
||||
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:
|
||||
// Static methods to construct a ConstantExpr of different kinds. Note that
|
||||
// these methods may return a object that is not an instance of the
|
||||
@ -822,9 +767,7 @@ class ConstantExpr : public Constant {
|
||||
|
||||
/// Select constant expr
|
||||
///
|
||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
|
||||
return getSelectTy(V1->getType(), C, V1, V2);
|
||||
}
|
||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
|
||||
|
||||
/// get - Return a binary or shift operator constant expression,
|
||||
/// folding if possible.
|
||||
@ -846,7 +789,9 @@ class ConstantExpr : public Constant {
|
||||
///
|
||||
static Constant *getGetElementPtr(Constant *C,
|
||||
Constant *const *IdxList, unsigned NumIdx,
|
||||
bool InBounds = false);
|
||||
bool InBounds = false) {
|
||||
return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds);
|
||||
}
|
||||
static Constant *getGetElementPtr(Constant *C,
|
||||
Value *const *IdxList, unsigned NumIdx,
|
||||
bool InBounds = false);
|
||||
@ -867,14 +812,9 @@ class ConstantExpr : public Constant {
|
||||
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
|
||||
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
|
||||
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
|
||||
static Constant *getExtractValue(Constant *Agg,
|
||||
const unsigned *IdxList, unsigned NumIdx);
|
||||
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
|
||||
static Constant *getInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx);
|
||||
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue.
|
||||
virtual bool isNullValue() const { return false; }
|
||||
ArrayRef<unsigned> Idxs);
|
||||
|
||||
/// getOpcode - Return the opcode at the root of this constant expression
|
||||
unsigned getOpcode() const { return getSubclassDataFromValue(); }
|
||||
@ -895,10 +835,18 @@ class ConstantExpr : public Constant {
|
||||
Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
|
||||
|
||||
/// getWithOperands - This returns the current constant expression with the
|
||||
/// operands replaced with the specified values. The specified operands must
|
||||
/// match count and type with the existing ones.
|
||||
Constant *getWithOperands(ArrayRef<Constant*> Ops) const;
|
||||
|
||||
/// operands replaced with the specified values. The specified array must
|
||||
/// have the same number of operands as our current one.
|
||||
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 replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
|
||||
|
||||
@ -950,10 +898,6 @@ class UndefValue : public Constant {
|
||||
///
|
||||
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();
|
||||
|
||||
/// 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 DeadArgEliminationID;
|
||||
extern unsigned char DeadStoreEliminationID;
|
||||
extern unsigned char DeadTypeEliminationID;
|
||||
extern unsigned char EarlyCSEID;
|
||||
extern unsigned char FunctionAttrsID;
|
||||
extern unsigned char FunctionInliningID;
|
||||
|
@ -19,76 +19,27 @@
|
||||
#define LLVM_DERIVED_TYPES_H
|
||||
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Value;
|
||||
template<class ValType, class TypeClass> class TypeMap;
|
||||
class FunctionValType;
|
||||
class ArrayValType;
|
||||
class StructValType;
|
||||
class PointerValType;
|
||||
class VectorValType;
|
||||
class IntegerValType;
|
||||
class APInt;
|
||||
class LLVMContext;
|
||||
|
||||
class DerivedType : public Type {
|
||||
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();
|
||||
}
|
||||
};
|
||||
template<typename T> class ArrayRef;
|
||||
class StringRef;
|
||||
|
||||
/// Class to represent integer types. Note that this class is also used to
|
||||
/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
|
||||
/// Int64Ty.
|
||||
/// @brief Integer representation type
|
||||
class IntegerType : public DerivedType {
|
||||
class IntegerType : public Type {
|
||||
friend class LLVMContextImpl;
|
||||
|
||||
protected:
|
||||
explicit IntegerType(LLVMContext &C, unsigned NumBits) :
|
||||
DerivedType(C, IntegerTyID) {
|
||||
explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){
|
||||
setSubclassData(NumBits);
|
||||
}
|
||||
friend class TypeMap<IntegerValType, IntegerType>;
|
||||
public:
|
||||
/// This enum is just used to hold constants we need for IntegerType.
|
||||
enum {
|
||||
@ -103,7 +54,7 @@ class IntegerType : public DerivedType {
|
||||
/// that instance will be returned. Otherwise a new one will be created. Only
|
||||
/// one instance with a given NumBits value is ever created.
|
||||
/// @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
|
||||
unsigned getBitWidth() const { return getSubclassData(); }
|
||||
@ -132,7 +83,7 @@ class IntegerType : public DerivedType {
|
||||
/// @brief Is this a power-of-2 byte-width IntegerType ?
|
||||
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 Type *T) {
|
||||
return T->getTypeID() == IntegerTyID;
|
||||
@ -142,34 +93,22 @@ class IntegerType : public DerivedType {
|
||||
|
||||
/// FunctionType - Class to represent function types
|
||||
///
|
||||
class FunctionType : public DerivedType {
|
||||
friend class TypeMap<FunctionValType, FunctionType>;
|
||||
bool isVarArgs;
|
||||
|
||||
class FunctionType : public Type {
|
||||
FunctionType(const FunctionType &); // Do not implement
|
||||
const FunctionType &operator=(const FunctionType &); // Do not implement
|
||||
FunctionType(const Type *Result, ArrayRef<const Type*> Params,
|
||||
bool IsVarArgs);
|
||||
FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
|
||||
|
||||
public:
|
||||
/// FunctionType::get - This static method is the primary way of constructing
|
||||
/// a FunctionType.
|
||||
///
|
||||
static FunctionType *get(
|
||||
const Type *Result, ///< The result type
|
||||
ArrayRef<const Type*> Params, ///< The types of the parameters
|
||||
bool isVarArg ///< Whether this is a variable argument length function
|
||||
);
|
||||
static FunctionType *get(const Type *Result,
|
||||
ArrayRef<Type*> Params, bool isVarArg);
|
||||
|
||||
/// FunctionType::get - Create a FunctionType taking no parameters.
|
||||
///
|
||||
static FunctionType *get(
|
||||
const Type *Result, ///< The result type
|
||||
bool isVarArg ///< Whether this is a variable argument length function
|
||||
) {
|
||||
return get(Result, ArrayRef<const Type *>(), isVarArg);
|
||||
}
|
||||
|
||||
static FunctionType *get(const Type *Result, bool isVarArg);
|
||||
|
||||
/// isValidReturnType - Return true if the specified type is valid as a return
|
||||
/// type.
|
||||
static bool isValidReturnType(const Type *RetTy);
|
||||
@ -178,26 +117,22 @@ class FunctionType : public DerivedType {
|
||||
/// argument type.
|
||||
static bool isValidArgumentType(const Type *ArgTy);
|
||||
|
||||
inline bool isVarArg() const { return isVarArgs; }
|
||||
inline const Type *getReturnType() const { return ContainedTys[0]; }
|
||||
bool isVarArg() const { return getSubclassData(); }
|
||||
Type *getReturnType() const { return ContainedTys[0]; }
|
||||
|
||||
typedef Type::subtype_iterator param_iterator;
|
||||
param_iterator param_begin() const { return ContainedTys + 1; }
|
||||
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
|
||||
|
||||
// Parameter type accessors...
|
||||
const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
|
||||
// Parameter type accessors.
|
||||
Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
|
||||
|
||||
/// getNumParams - Return the number of fixed parameters this function type
|
||||
/// requires. This does not consider varargs.
|
||||
///
|
||||
unsigned getNumParams() const { return NumContainedTys - 1; }
|
||||
|
||||
// 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:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const FunctionType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
return T->getTypeID() == FunctionTyID;
|
||||
@ -206,22 +141,21 @@ class FunctionType : public DerivedType {
|
||||
|
||||
|
||||
/// CompositeType - Common super class of ArrayType, StructType, PointerType
|
||||
/// and VectorType
|
||||
class CompositeType : public DerivedType {
|
||||
/// and VectorType.
|
||||
class CompositeType : public Type {
|
||||
protected:
|
||||
inline explicit CompositeType(LLVMContext &C, TypeID id) :
|
||||
DerivedType(C, id) { }
|
||||
explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { }
|
||||
public:
|
||||
|
||||
/// getTypeAtIndex - Given an index value into the type, return the type of
|
||||
/// the element.
|
||||
///
|
||||
virtual const Type *getTypeAtIndex(const Value *V) const = 0;
|
||||
virtual const Type *getTypeAtIndex(unsigned Idx) const = 0;
|
||||
virtual bool indexValid(const Value *V) const = 0;
|
||||
virtual bool indexValid(unsigned Idx) const = 0;
|
||||
Type *getTypeAtIndex(const Value *V) const;
|
||||
Type *getTypeAtIndex(unsigned Idx) const;
|
||||
bool indexValid(const Value *V) const;
|
||||
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 Type *T) {
|
||||
return T->getTypeID() == ArrayTyID ||
|
||||
@ -232,69 +166,114 @@ class CompositeType : public DerivedType {
|
||||
};
|
||||
|
||||
|
||||
/// 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 {
|
||||
friend class TypeMap<StructValType, StructType>;
|
||||
StructType(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:
|
||||
~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.
|
||||
///
|
||||
static StructType *get(LLVMContext &Context,
|
||||
ArrayRef<const Type*> Params,
|
||||
bool isPacked=false);
|
||||
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
|
||||
bool isPacked = false);
|
||||
|
||||
/// StructType::get - Create an empty structure type.
|
||||
///
|
||||
static StructType *get(LLVMContext &Context, bool isPacked=false) {
|
||||
return get(Context, llvm::ArrayRef<const Type*>(), isPacked);
|
||||
}
|
||||
static StructType *get(LLVMContext &Context, bool isPacked = false);
|
||||
|
||||
/// 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
|
||||
/// creating structure types by specifying the elements as arguments.
|
||||
/// Note that this method always returns a non-packed struct. To get
|
||||
/// an empty struct, pass NULL, NULL.
|
||||
static StructType *get(LLVMContext &Context,
|
||||
const Type *type, ...) END_WITH_NULL;
|
||||
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
|
||||
|
||||
/// isAnonymous - Return true if this type is uniqued by structural
|
||||
/// equivalence, false if it has an identity.
|
||||
bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;}
|
||||
|
||||
/// 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
|
||||
/// element type.
|
||||
static bool isValidElementType(const Type *ElemTy);
|
||||
|
||||
|
||||
// Iterator access to the elements
|
||||
// Iterator access to the elements.
|
||||
typedef Type::subtype_iterator element_iterator;
|
||||
element_iterator element_begin() const { return ContainedTys; }
|
||||
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
|
||||
unsigned getNumElements() const { return NumContainedTys; }
|
||||
const Type *getElementType(unsigned N) const {
|
||||
Type *getElementType(unsigned N) const {
|
||||
assert(N < NumContainedTys && "Element number out of range!");
|
||||
return ContainedTys[N];
|
||||
}
|
||||
|
||||
/// getTypeAtIndex - Given an index value into the type, return the type of
|
||||
/// 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:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const StructType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
return T->getTypeID() == StructTyID;
|
||||
}
|
||||
|
||||
bool isPacked() const { return (0 != getSubclassData()) ? true : false; }
|
||||
};
|
||||
|
||||
/// SequentialType - This is the superclass of the array, pointer and vector
|
||||
@ -306,38 +285,21 @@ class StructType : public CompositeType {
|
||||
/// components out in memory identically.
|
||||
///
|
||||
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!
|
||||
const SequentialType &operator=(const SequentialType &); // Do not implement!
|
||||
|
||||
// avoiding warning: 'this' : used in base member initializer list
|
||||
SequentialType* this_() { return this; }
|
||||
protected:
|
||||
SequentialType(TypeID TID, const Type *ElType)
|
||||
: CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) {
|
||||
SequentialType(TypeID TID, Type *ElType)
|
||||
: CompositeType(ElType->getContext(), TID), ContainedType(ElType) {
|
||||
ContainedTys = &ContainedType;
|
||||
NumContainedTys = 1;
|
||||
}
|
||||
|
||||
public:
|
||||
inline const Type *getElementType() const { return ContainedTys[0]; }
|
||||
Type *getElementType() const { return ContainedTys[0]; }
|
||||
|
||||
virtual bool indexValid(const Value *V) const;
|
||||
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:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const SequentialType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
return T->getTypeID() == ArrayTyID ||
|
||||
@ -347,15 +309,14 @@ class SequentialType : public CompositeType {
|
||||
};
|
||||
|
||||
|
||||
/// ArrayType - Class to represent array types
|
||||
/// ArrayType - Class to represent array types.
|
||||
///
|
||||
class ArrayType : public SequentialType {
|
||||
friend class TypeMap<ArrayValType, ArrayType>;
|
||||
uint64_t NumElements;
|
||||
|
||||
ArrayType(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:
|
||||
/// ArrayType::get - This static method is the primary way to construct an
|
||||
/// ArrayType
|
||||
@ -366,31 +327,26 @@ class ArrayType : public SequentialType {
|
||||
/// element type.
|
||||
static bool isValidElementType(const Type *ElemTy);
|
||||
|
||||
inline uint64_t getNumElements() const { return NumElements; }
|
||||
uint64_t getNumElements() const { return NumElements; }
|
||||
|
||||
// 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:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const ArrayType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
return T->getTypeID() == ArrayTyID;
|
||||
}
|
||||
};
|
||||
|
||||
/// VectorType - Class to represent vector types
|
||||
/// VectorType - Class to represent vector types.
|
||||
///
|
||||
class VectorType : public SequentialType {
|
||||
friend class TypeMap<VectorValType, VectorType>;
|
||||
unsigned NumElements;
|
||||
|
||||
VectorType(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:
|
||||
/// VectorType::get - This static method is the primary way to construct an
|
||||
/// VectorType
|
||||
/// VectorType.
|
||||
///
|
||||
static VectorType *get(const Type *ElementType, unsigned NumElements);
|
||||
|
||||
@ -400,7 +356,7 @@ class VectorType : public SequentialType {
|
||||
///
|
||||
static VectorType *getInteger(const VectorType *VTy) {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -410,7 +366,7 @@ class VectorType : public SequentialType {
|
||||
///
|
||||
static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -422,7 +378,7 @@ class VectorType : public SequentialType {
|
||||
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
|
||||
assert((EltBits & 1) == 0 &&
|
||||
"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());
|
||||
}
|
||||
|
||||
@ -431,18 +387,14 @@ class VectorType : public SequentialType {
|
||||
static bool isValidElementType(const Type *ElemTy);
|
||||
|
||||
/// @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.
|
||||
inline unsigned getBitWidth() const {
|
||||
unsigned getBitWidth() const {
|
||||
return NumElements * getElementType()->getPrimitiveSizeInBits();
|
||||
}
|
||||
|
||||
// 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:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const VectorType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
return T->getTypeID() == VectorTyID;
|
||||
@ -450,15 +402,12 @@ class VectorType : public SequentialType {
|
||||
};
|
||||
|
||||
|
||||
/// PointerType - Class to represent pointers
|
||||
/// PointerType - Class to represent pointers.
|
||||
///
|
||||
class PointerType : public SequentialType {
|
||||
friend class TypeMap<PointerValType, PointerType>;
|
||||
unsigned AddressSpace;
|
||||
|
||||
PointerType(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:
|
||||
/// PointerType::get - This constructs a pointer to an object of the specified
|
||||
/// type in a numbered address space.
|
||||
@ -475,39 +424,15 @@ class PointerType : public SequentialType {
|
||||
static bool isValidElementType(const Type *ElemTy);
|
||||
|
||||
/// @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.
|
||||
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:
|
||||
// Implement support type inquiry through isa, cast, and dyn_cast.
|
||||
static inline bool classof(const PointerType *) { return true; }
|
||||
static inline bool classof(const Type *T) {
|
||||
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
|
||||
|
||||
#endif
|
||||
|
@ -53,6 +53,7 @@ class RuntimeDyld {
|
||||
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
|
||||
// interface.
|
||||
RuntimeDyldImpl *Dyld;
|
||||
RTDyldMemoryManager *MM;
|
||||
public:
|
||||
RuntimeDyld(RTDyldMemoryManager*);
|
||||
~RuntimeDyld();
|
||||
|
@ -128,8 +128,8 @@ class Function : public GlobalValue,
|
||||
|
||||
~Function();
|
||||
|
||||
const Type *getReturnType() const; // Return the type of the ret val
|
||||
const FunctionType *getFunctionType() const; // Return the FunctionType for me
|
||||
Type *getReturnType() const; // Return the type of the ret val
|
||||
FunctionType *getFunctionType() const; // Return the FunctionType for me
|
||||
|
||||
/// getContext - Return a pointer to the LLVMContext associated with this
|
||||
/// function, or NULL if this function is not bound to a context yet.
|
||||
@ -139,12 +139,6 @@ class Function : public GlobalValue,
|
||||
/// arguments.
|
||||
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
|
||||
/// 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
|
||||
|
@ -47,11 +47,6 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
|
||||
/// Provide fast operand accessors
|
||||
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,
|
||||
/// but does not delete it.
|
||||
///
|
||||
@ -63,23 +58,23 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
|
||||
virtual void eraseFromParent();
|
||||
|
||||
/// set/getAliasee - These methods retrive and set alias target.
|
||||
void setAliasee(Constant* GV);
|
||||
const Constant* getAliasee() const {
|
||||
void setAliasee(Constant *GV);
|
||||
const Constant *getAliasee() const {
|
||||
return cast_or_null<Constant>(getOperand(0));
|
||||
}
|
||||
Constant* getAliasee() {
|
||||
Constant *getAliasee() {
|
||||
return cast_or_null<Constant>(getOperand(0));
|
||||
}
|
||||
/// getAliasedGlobal() - Aliasee can be either global or bitcast of
|
||||
/// 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
|
||||
/// 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
|
||||
/// the whole chain aliasing chain is traversed, otherwise - only strong
|
||||
/// 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:
|
||||
static inline bool classof(const GlobalAlias *) { return true; }
|
||||
|
@ -106,8 +106,8 @@ class GlobalValue : public Constant {
|
||||
bool use_empty_except_constants();
|
||||
|
||||
/// getType - Global values are always pointers.
|
||||
inline const PointerType *getType() const {
|
||||
return reinterpret_cast<const PointerType*>(User::getType());
|
||||
inline PointerType *getType() const {
|
||||
return reinterpret_cast<PointerType*>(User::getType());
|
||||
}
|
||||
|
||||
static LinkageTypes getLinkOnceLinkage(bool ODR) {
|
||||
@ -258,16 +258,12 @@ class GlobalValue : public Constant {
|
||||
|
||||
/// @}
|
||||
|
||||
/// 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.
|
||||
virtual void destroyConstant();
|
||||
|
||||
/// isDeclaration - Return true if the primary definition of this global
|
||||
/// value is outside of the current translation unit...
|
||||
virtual bool isDeclaration() const = 0;
|
||||
/// value is outside of the current translation unit.
|
||||
bool isDeclaration() const;
|
||||
|
||||
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||
/// but does not delete it.
|
||||
|
@ -68,11 +68,6 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
|
||||
/// Provide fast operand accessors
|
||||
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
|
||||
/// initializer. The initializer for the global variable/constant is held by
|
||||
/// Initializer if an initializer is specified.
|
||||
@ -119,7 +114,7 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
|
||||
/// illegal to call this method if the global is external, because we cannot
|
||||
/// 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!");
|
||||
return static_cast<Constant*>(Op<0>().get());
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ void initializeArgPromotionPass(PassRegistry&);
|
||||
void initializeBasicAliasAnalysisPass(PassRegistry&);
|
||||
void initializeBasicCallGraphPass(PassRegistry&);
|
||||
void initializeBlockExtractorPassPass(PassRegistry&);
|
||||
void initializeBlockFrequencyPass(PassRegistry&);
|
||||
void initializeBlockPlacementPass(PassRegistry&);
|
||||
void initializeBranchProbabilityInfoPass(PassRegistry&);
|
||||
void initializeBreakCriticalEdgesPass(PassRegistry&);
|
||||
@ -83,7 +84,6 @@ void initializeDAEPass(PassRegistry&);
|
||||
void initializeDAHPass(PassRegistry&);
|
||||
void initializeDCEPass(PassRegistry&);
|
||||
void initializeDSEPass(PassRegistry&);
|
||||
void initializeDTEPass(PassRegistry&);
|
||||
void initializeDeadInstEliminationPass(PassRegistry&);
|
||||
void initializeDeadMachineInstructionElimPass(PassRegistry&);
|
||||
void initializeDomOnlyPrinterPass(PassRegistry&);
|
||||
@ -140,10 +140,13 @@ void initializeLoopUnrollPass(PassRegistry&);
|
||||
void initializeLoopUnswitchPass(PassRegistry&);
|
||||
void initializeLoopIdiomRecognizePass(PassRegistry&);
|
||||
void initializeLowerAtomicPass(PassRegistry&);
|
||||
void initializeLowerExpectIntrinsicPass(PassRegistry&);
|
||||
void initializeLowerIntrinsicsPass(PassRegistry&);
|
||||
void initializeLowerInvokePass(PassRegistry&);
|
||||
void initializeLowerSetJmpPass(PassRegistry&);
|
||||
void initializeLowerSwitchPass(PassRegistry&);
|
||||
void initializeMachineBlockFrequencyPass(PassRegistry&);
|
||||
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
|
||||
void initializeMachineCSEPass(PassRegistry&);
|
||||
void initializeMachineDominatorTreePass(PassRegistry&);
|
||||
void initializeMachineLICMPass(PassRegistry&);
|
||||
@ -160,6 +163,10 @@ void initializeModuleDebugInfoPrinterPass(PassRegistry&);
|
||||
void initializeNoAAPass(PassRegistry&);
|
||||
void initializeNoProfileInfoPass(PassRegistry&);
|
||||
void initializeNoPathProfileInfoPass(PassRegistry&);
|
||||
void initializeObjCARCAliasAnalysisPass(PassRegistry&);
|
||||
void initializeObjCARCExpandPass(PassRegistry&);
|
||||
void initializeObjCARCContractPass(PassRegistry&);
|
||||
void initializeObjCARCOptPass(PassRegistry&);
|
||||
void initializeOptimalEdgeProfilerPass(PassRegistry&);
|
||||
void initializeOptimizePHIsPass(PassRegistry&);
|
||||
void initializePEIPass(PassRegistry&);
|
||||
@ -171,7 +178,6 @@ void initializePostDomOnlyViewerPass(PassRegistry&);
|
||||
void initializePostDomPrinterPass(PassRegistry&);
|
||||
void initializePostDomViewerPass(PassRegistry&);
|
||||
void initializePostDominatorTreePass(PassRegistry&);
|
||||
void initializePreAllocSplittingPass(PassRegistry&);
|
||||
void initializePreVerifierPass(PassRegistry&);
|
||||
void initializePrintDbgInfoPass(PassRegistry&);
|
||||
void initializePrintFunctionPassPass(PassRegistry&);
|
||||
@ -192,7 +198,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&);
|
||||
void initializeRegionOnlyViewerPass(PassRegistry&);
|
||||
void initializeRegionPrinterPass(PassRegistry&);
|
||||
void initializeRegionViewerPass(PassRegistry&);
|
||||
void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
|
||||
void initializeRenderMachineFunctionPass(PassRegistry&);
|
||||
void initializeSCCPPass(PassRegistry&);
|
||||
void initializeSROA_DTPass(PassRegistry&);
|
||||
@ -200,7 +205,7 @@ void initializeSROA_SSAUpPass(PassRegistry&);
|
||||
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
|
||||
void initializeScalarEvolutionPass(PassRegistry&);
|
||||
void initializeSimpleInlinerPass(PassRegistry&);
|
||||
void initializeSimpleRegisterCoalescingPass(PassRegistry&);
|
||||
void initializeRegisterCoalescerPass(PassRegistry&);
|
||||
void initializeSimplifyLibCallsPass(PassRegistry&);
|
||||
void initializeSingleLoopExtractorPass(PassRegistry&);
|
||||
void initializeSinkingPass(PassRegistry&);
|
||||
|
@ -25,15 +25,16 @@ class PointerType;
|
||||
class FunctionType;
|
||||
class Module;
|
||||
struct InlineAsmKeyType;
|
||||
template<class ValType, class TypeClass, class ConstantClass, bool HasLargeKey>
|
||||
template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
|
||||
bool HasLargeKey>
|
||||
class ConstantUniqueMap;
|
||||
template<class ConstantClass, class TypeClass, class ValType>
|
||||
struct ConstantCreator;
|
||||
|
||||
class InlineAsm : public Value {
|
||||
friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
|
||||
friend class ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm,
|
||||
false>;
|
||||
friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
|
||||
PointerType, InlineAsm, false>;
|
||||
|
||||
InlineAsm(const InlineAsm &); // do not implement
|
||||
void operator=(const InlineAsm&); // do not implement
|
||||
@ -63,13 +64,13 @@ class InlineAsm : public Value {
|
||||
|
||||
/// getType - InlineAsm's are always pointers.
|
||||
///
|
||||
const PointerType *getType() const {
|
||||
return reinterpret_cast<const PointerType*>(Value::getType());
|
||||
PointerType *getType() const {
|
||||
return reinterpret_cast<PointerType*>(Value::getType());
|
||||
}
|
||||
|
||||
/// 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 &getConstraintString() const { return Constraints; }
|
||||
@ -187,25 +188,32 @@ class InlineAsm : public Value {
|
||||
// in the backend.
|
||||
|
||||
enum {
|
||||
// Fixed operands on an INLINEASM SDNode.
|
||||
Op_InputChain = 0,
|
||||
Op_AsmString = 1,
|
||||
Op_MDNode = 2,
|
||||
Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
|
||||
Op_FirstOperand = 4,
|
||||
|
||||
// Fixed operands on an INLINEASM MachineInstr.
|
||||
MIOp_AsmString = 0,
|
||||
MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
|
||||
MIOp_FirstOperand = 2,
|
||||
|
||||
// Interpretation of the MIOp_ExtraInfo bit field.
|
||||
Extra_HasSideEffects = 1,
|
||||
Extra_IsAlignStack = 2,
|
||||
|
||||
Kind_RegUse = 1,
|
||||
Kind_RegDef = 2,
|
||||
Kind_Imm = 3,
|
||||
Kind_Mem = 4,
|
||||
Kind_RegDefEarlyClobber = 6,
|
||||
|
||||
|
||||
// Inline asm operands map to multiple SDNode / MachineInstr operands.
|
||||
// The first operand is an immediate describing the asm operand, the low
|
||||
// bits is the kind:
|
||||
Kind_RegUse = 1, // Input register, "r".
|
||||
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
|
||||
};
|
||||
|
||||
@ -232,7 +240,10 @@ class InlineAsm : public Value {
|
||||
static bool isRegDefEarlyClobberKind(unsigned Flag) {
|
||||
return getKind(Flag) == Kind_RegDefEarlyClobber;
|
||||
}
|
||||
|
||||
static bool isClobberKind(unsigned Flag) {
|
||||
return getKind(Flag) == Kind_Clobber;
|
||||
}
|
||||
|
||||
/// getNumOperandRegisters - Extract the number of registers field from the
|
||||
/// inline asm operand flag.
|
||||
static unsigned getNumOperandRegisters(unsigned Flag) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <iterator>
|
||||
|
||||
@ -76,7 +77,7 @@ class AllocaInst : public UnaryInstruction {
|
||||
/// getAllocatedType - Return the type that is being allocated by the
|
||||
/// instruction.
|
||||
///
|
||||
const Type *getAllocatedType() const;
|
||||
Type *getAllocatedType() const;
|
||||
|
||||
/// getAlignment - Return the alignment of the memory that is being allocated
|
||||
/// by the instruction.
|
||||
@ -271,10 +272,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
|
||||
// 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.
|
||||
//
|
||||
static inline const Type *checkType(const Type *Ty) {
|
||||
static inline const Type *checkGEPType(const Type *Ty) {
|
||||
assert(Ty && "Invalid GetElementPtrInst indices for type!");
|
||||
return Ty;
|
||||
}
|
||||
@ -315,13 +316,13 @@ class GetElementPtrInst : public Instruction {
|
||||
/// pointer type.
|
||||
///
|
||||
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) {
|
||||
static 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)
|
||||
@ -446,24 +447,22 @@ class GetElementPtrInst : public Instruction {
|
||||
/// pointer type.
|
||||
///
|
||||
template<typename RandomAccessIterator>
|
||||
static const Type *getIndexedType(const Type *Ptr,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd) {
|
||||
static 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,
|
||||
Value* const *Idx, unsigned NumIdx);
|
||||
// FIXME: Use ArrayRef
|
||||
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,
|
||||
Constant* const *Idx, unsigned NumIdx);
|
||||
|
||||
static const Type *getIndexedType(const Type *Ptr,
|
||||
uint64_t const *Idx, unsigned NumIdx);
|
||||
|
||||
static const Type *getIndexedType(const Type *Ptr, Value *Idx);
|
||||
static Type *getIndexedType(const Type *Ptr,
|
||||
uint64_t const *Idx, unsigned NumIdx);
|
||||
static Type *getIndexedType(const Type *Ptr, Value *Idx);
|
||||
|
||||
inline op_iterator idx_begin() { 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,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(PointerType::get(checkType(
|
||||
: Instruction(PointerType::get(checkGEPType(
|
||||
getIndexedType(Ptr->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
cast<PointerType>(Ptr->getType())
|
||||
@ -557,7 +556,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr,
|
||||
unsigned Values,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(PointerType::get(checkType(
|
||||
: Instruction(PointerType::get(checkGEPType(
|
||||
getIndexedType(Ptr->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
cast<PointerType>(Ptr->getType())
|
||||
@ -843,46 +842,17 @@ class FCmpInst: public CmpInst {
|
||||
class CallInst : public Instruction {
|
||||
AttrListPtr AttributeList; ///< parameter attributes for call
|
||||
CallInst(const CallInst &CI);
|
||||
void init(Value *Func, Value* const *Params, unsigned NumParams);
|
||||
void init(Value *Func, Value *Actual1, Value *Actual2);
|
||||
void init(Value *Func, Value *Actual);
|
||||
void init(Value *Func);
|
||||
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
|
||||
void init(Value *Func, const Twine &NameStr);
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
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.
|
||||
/// Construct a CallInst given a range of arguments.
|
||||
/// @brief Construct a CallInst from a range of arguments
|
||||
template<typename RandomAccessIterator>
|
||||
CallInst(Value *Func,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
const Twine &NameStr, Instruction *InsertBefore);
|
||||
inline CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, Instruction *InsertBefore);
|
||||
|
||||
/// 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.
|
||||
/// Construct a CallInst given a range of arguments.
|
||||
/// @brief Construct a CallInst from a range of arguments
|
||||
template<typename RandomAccessIterator>
|
||||
inline CallInst(Value *Func,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
inline CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
CallInst(Value *F, Value *Actual, const Twine &NameStr,
|
||||
@ -895,31 +865,18 @@ class CallInst : public Instruction {
|
||||
protected:
|
||||
virtual CallInst *clone_impl() const;
|
||||
public:
|
||||
template<typename RandomAccessIterator>
|
||||
static CallInst *Create(Value *Func,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
ArrayRef<Value *> Args,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new(unsigned(ArgEnd - ArgBegin + 1))
|
||||
CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertBefore);
|
||||
return new(unsigned(Args.size() + 1))
|
||||
CallInst(Func, Args, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static CallInst *Create(Value *Func,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return new(unsigned(ArgEnd - ArgBegin + 1))
|
||||
CallInst(Func, ArgBegin, ArgEnd, 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);
|
||||
return new(unsigned(Args.size() + 1))
|
||||
CallInst(Func, Args, NameStr, InsertAtEnd);
|
||||
}
|
||||
static CallInst *Create(Value *F, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
@ -1094,32 +1051,24 @@ template <>
|
||||
struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> {
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
CallInst::CallInst(Value *Func,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd)
|
||||
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
|
||||
->getElementType())->getReturnType(),
|
||||
Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1),
|
||||
unsigned(ArgEnd - ArgBegin + 1), InsertAtEnd) {
|
||||
init(Func, ArgBegin, ArgEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
|
||||
unsigned(Args.size() + 1), InsertAtEnd) {
|
||||
init(Func, Args, NameStr);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
CallInst::CallInst(Value *Func,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, Instruction *InsertBefore)
|
||||
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
|
||||
->getElementType())->getReturnType(),
|
||||
Instruction::Call,
|
||||
OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1),
|
||||
unsigned(ArgEnd - ArgBegin + 1), InsertBefore) {
|
||||
init(Func, ArgBegin, ArgEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
|
||||
unsigned(Args.size() + 1), InsertBefore) {
|
||||
init(Func, Args, NameStr);
|
||||
}
|
||||
|
||||
|
||||
@ -1430,69 +1379,18 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
|
||||
ExtractValueInst(const ExtractValueInst &EVI);
|
||||
void init(const unsigned *Idx, unsigned NumIdx,
|
||||
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);
|
||||
}
|
||||
void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
|
||||
|
||||
/// Constructors - Create a extractvalue instruction with a base aggregate
|
||||
/// value and a list of indices. The first ctor can optionally insert before
|
||||
/// an existing instruction, the second appends the new instruction to the
|
||||
/// specified BasicBlock.
|
||||
template<typename RandomAccessIterator>
|
||||
inline ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
template<typename RandomAccessIterator>
|
||||
inline ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
// allocate space for exactly one operand
|
||||
@ -1503,54 +1401,25 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
virtual ExtractValueInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
template<typename RandomAccessIterator>
|
||||
static ExtractValueInst *Create(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new
|
||||
ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertBefore);
|
||||
ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static ExtractValueInst *Create(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new ExtractValueInst(Agg, IdxBegin, IdxEnd, 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);
|
||||
return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
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);
|
||||
static Type *getIndexedType(const Type *Agg, ArrayRef<unsigned> Idxs);
|
||||
|
||||
typedef const unsigned* idx_iterator;
|
||||
inline idx_iterator idx_begin() const { return Indices.begin(); }
|
||||
@ -1566,7 +1435,11 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -1584,31 +1457,21 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: UnaryInstruction(checkType(getIndexedType(Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
|
||||
ExtractValue, Agg, InsertBefore) {
|
||||
init(IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Idxs, NameStr);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: UnaryInstruction(checkType(getIndexedType(Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
|
||||
ExtractValue, Agg, InsertAtEnd) {
|
||||
init(IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Idxs, NameStr);
|
||||
}
|
||||
|
||||
|
||||
@ -1624,44 +1487,19 @@ class InsertValueInst : public Instruction {
|
||||
|
||||
void *operator new(size_t, unsigned); // Do not implement
|
||||
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);
|
||||
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
|
||||
/// value, a value to insert, and a list of indices. The first ctor can
|
||||
/// optionally insert before an existing instruction, the second appends
|
||||
/// the new instruction to the specified BasicBlock.
|
||||
template<typename RandomAccessIterator>
|
||||
inline InsertValueInst(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
template<typename RandomAccessIterator>
|
||||
inline InsertValueInst(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
/// Constructors - These two constructors are convenience methods because one
|
||||
@ -1679,37 +1517,17 @@ class InsertValueInst : public Instruction {
|
||||
return User::operator new(s, 2);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
NameStr, InsertBefore);
|
||||
return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
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);
|
||||
return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
@ -1739,7 +1557,11 @@ class InsertValueInst : public Instruction {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -1762,33 +1584,25 @@ struct OperandTraits<InsertValueInst> :
|
||||
public FixedNumOperandTraits<InsertValueInst, 2> {
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertBefore) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Agg, Val, Idxs, NameStr);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertAtEnd) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Agg, Val, Idxs, NameStr);
|
||||
}
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
|
||||
@ -1814,7 +1628,7 @@ class PHINode : public Instruction {
|
||||
explicit PHINode(const Type *Ty, unsigned NumReservedValues,
|
||||
const Twine &NameStr = "", Instruction *InsertBefore = 0)
|
||||
: Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
|
||||
ReservedSpace(NumReservedValues * 2) {
|
||||
ReservedSpace(NumReservedValues) {
|
||||
setName(NameStr);
|
||||
OperandList = allocHungoffUses(ReservedSpace);
|
||||
}
|
||||
@ -1822,11 +1636,16 @@ class PHINode : public Instruction {
|
||||
PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
|
||||
ReservedSpace(NumReservedValues * 2) {
|
||||
ReservedSpace(NumReservedValues) {
|
||||
setName(NameStr);
|
||||
OperandList = allocHungoffUses(ReservedSpace);
|
||||
}
|
||||
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;
|
||||
public:
|
||||
/// Constructors - NumReservedValues is a hint for the number of incoming
|
||||
@ -1845,32 +1664,55 @@ class PHINode : public Instruction {
|
||||
/// Provide fast operand accessors
|
||||
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
|
||||
///
|
||||
unsigned getNumIncomingValues() const { return getNumOperands()/2; }
|
||||
unsigned getNumIncomingValues() const { return getNumOperands(); }
|
||||
|
||||
/// getIncomingValue - Return incoming value number x
|
||||
///
|
||||
Value *getIncomingValue(unsigned i) const {
|
||||
assert(i*2 < getNumOperands() && "Invalid value number!");
|
||||
return getOperand(i*2);
|
||||
return getOperand(i);
|
||||
}
|
||||
void setIncomingValue(unsigned i, Value *V) {
|
||||
assert(i*2 < getNumOperands() && "Invalid value number!");
|
||||
setOperand(i*2, V);
|
||||
setOperand(i, V);
|
||||
}
|
||||
static unsigned getOperandNumForIncomingValue(unsigned i) {
|
||||
return i*2;
|
||||
return i;
|
||||
}
|
||||
static unsigned getIncomingValueNumForOperand(unsigned i) {
|
||||
assert(i % 2 == 0 && "Invalid incoming-value operand index!");
|
||||
return i/2;
|
||||
return i;
|
||||
}
|
||||
|
||||
/// getIncomingBlock - Return incoming basic block number @p i.
|
||||
///
|
||||
BasicBlock *getIncomingBlock(unsigned i) const {
|
||||
return cast<BasicBlock>(getOperand(i*2+1));
|
||||
return block_begin()[i];
|
||||
}
|
||||
|
||||
/// getIncomingBlock - Return incoming basic block corresponding
|
||||
@ -1878,7 +1720,7 @@ class PHINode : public Instruction {
|
||||
///
|
||||
BasicBlock *getIncomingBlock(const Use &U) const {
|
||||
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
|
||||
@ -1889,16 +1731,8 @@ class PHINode : public Instruction {
|
||||
return getIncomingBlock(I.getUse());
|
||||
}
|
||||
|
||||
|
||||
void setIncomingBlock(unsigned i, BasicBlock *BB) {
|
||||
setOperand(i*2+1, (Value*)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;
|
||||
block_begin()[i] = BB;
|
||||
}
|
||||
|
||||
/// addIncoming - Add an incoming value to the end of the PHI list
|
||||
@ -1908,13 +1742,12 @@ class PHINode : public Instruction {
|
||||
assert(BB && "PHI node got a null basic block!");
|
||||
assert(getType() == V->getType() &&
|
||||
"All operands to PHI node must be the same type as the PHI node!");
|
||||
unsigned OpNo = NumOperands;
|
||||
if (OpNo+2 > ReservedSpace)
|
||||
if (NumOperands == ReservedSpace)
|
||||
growOperands(); // Get more space!
|
||||
// Initialize some new operands.
|
||||
NumOperands = OpNo+2;
|
||||
OperandList[OpNo] = V;
|
||||
OperandList[OpNo+1] = (Value*)BB;
|
||||
++NumOperands;
|
||||
setIncomingValue(NumOperands - 1, V);
|
||||
setIncomingBlock(NumOperands - 1, BB);
|
||||
}
|
||||
|
||||
/// removeIncomingValue - Remove an incoming value. This is useful if a
|
||||
@ -1937,14 +1770,16 @@ class PHINode : public Instruction {
|
||||
/// block in the value list for this PHI. Returns -1 if no instance.
|
||||
///
|
||||
int getBasicBlockIndex(const BasicBlock *BB) const {
|
||||
Use *OL = OperandList;
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; i += 2)
|
||||
if (OL[i+1].get() == (const Value*)BB) return i/2;
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
||||
if (block_begin()[i] == BB)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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
|
||||
@ -2397,71 +2232,39 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
|
||||
class InvokeInst : public TerminatorInst {
|
||||
AttrListPtr AttributeList;
|
||||
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,
|
||||
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, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs);
|
||||
setName(NameStr);
|
||||
}
|
||||
ArrayRef<Value *> Args, const Twine &NameStr);
|
||||
|
||||
/// 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
|
||||
template<typename RandomAccessIterator>
|
||||
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
unsigned Values,
|
||||
ArrayRef<Value *> Args, unsigned Values,
|
||||
const Twine &NameStr, Instruction *InsertBefore);
|
||||
|
||||
/// 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
|
||||
template<typename RandomAccessIterator>
|
||||
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd,
|
||||
unsigned Values,
|
||||
ArrayRef<Value *> Args, unsigned Values,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual InvokeInst *clone_impl() const;
|
||||
public:
|
||||
template<typename RandomAccessIterator>
|
||||
static InvokeInst *Create(Value *Func,
|
||||
BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
const Twine &NameStr = "",
|
||||
ArrayRef<Value *> Args, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
unsigned Values(ArgEnd - ArgBegin + 3);
|
||||
return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd,
|
||||
unsigned Values = unsigned(Args.size()) + 3;
|
||||
return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
|
||||
Values, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static InvokeInst *Create(Value *Func,
|
||||
BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
const Twine &NameStr,
|
||||
ArrayRef<Value *> Args, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
unsigned Values(ArgEnd - ArgBegin + 3);
|
||||
return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd,
|
||||
unsigned Values = unsigned(Args.size()) + 3;
|
||||
return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
|
||||
Values, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
@ -2627,37 +2430,27 @@ template <>
|
||||
struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
InvokeInst::InvokeInst(Value *Func,
|
||||
BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
unsigned Values,
|
||||
ArrayRef<Value *> Args, unsigned Values,
|
||||
const Twine &NameStr, Instruction *InsertBefore)
|
||||
: TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
|
||||
->getElementType())->getReturnType(),
|
||||
Instruction::Invoke,
|
||||
OperandTraits<InvokeInst>::op_end(this) - Values,
|
||||
Values, InsertBefore) {
|
||||
init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Func, IfNormal, IfException, Args, NameStr);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
InvokeInst::InvokeInst(Value *Func,
|
||||
BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
unsigned Values,
|
||||
ArrayRef<Value *> Args, unsigned Values,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd)
|
||||
: TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
|
||||
->getElementType())->getReturnType(),
|
||||
Instruction::Invoke,
|
||||
OperandTraits<InvokeInst>::op_end(this) - Values,
|
||||
Values, InsertAtEnd) {
|
||||
init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Func, IfNormal, IfException, Args, NameStr);
|
||||
}
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value)
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LLVM_INTRINSICS_H
|
||||
#define LLVM_INTRINSICS_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
@ -44,12 +45,12 @@ namespace Intrinsic {
|
||||
|
||||
/// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
|
||||
/// "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.
|
||||
///
|
||||
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
|
||||
/// overloaded.
|
||||
@ -67,8 +68,8 @@ namespace Intrinsic {
|
||||
/// 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
|
||||
/// intrinsic.
|
||||
Function *getDeclaration(Module *M, ID id, const Type **Tys = 0,
|
||||
unsigned numTys = 0);
|
||||
Function *getDeclaration(Module *M, ID id,
|
||||
ArrayRef<Type*> Tys = ArrayRef<Type*>());
|
||||
|
||||
/// Map a GCC builtin name to an intrinsic ID.
|
||||
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
|
||||
// with respect to nearby accesses to the same memory.
|
||||
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>]>;
|
||||
def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;
|
||||
|
||||
@ -254,6 +255,12 @@ let Properties = [IntrReadMem] in {
|
||||
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.
|
||||
def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_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]>,
|
||||
GCCBuiltin<"__builtin_object_size">;
|
||||
|
||||
//===------------------------- Expect Intrinsics --------------------------===//
|
||||
//
|
||||
def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
|
||||
LLVMMatchType<0>], [IntrNoMem]>;
|
||||
|
||||
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
|
||||
//
|
||||
|
||||
@ -311,7 +323,7 @@ let Properties = [IntrNoMem] in {
|
||||
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_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_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
|
||||
|
||||
|
@ -39,7 +39,8 @@ class LLVMContext {
|
||||
// compile-time performance optimization, not a correctness optimization.
|
||||
enum {
|
||||
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.
|
||||
|
@ -62,7 +62,6 @@ namespace {
|
||||
(void) llvm::createDeadCodeEliminationPass();
|
||||
(void) llvm::createDeadInstEliminationPass();
|
||||
(void) llvm::createDeadStoreEliminationPass();
|
||||
(void) llvm::createDeadTypeEliminationPass();
|
||||
(void) llvm::createDomOnlyPrinterPass();
|
||||
(void) llvm::createDomPrinterPass();
|
||||
(void) llvm::createDomOnlyViewerPass();
|
||||
@ -92,11 +91,16 @@ namespace {
|
||||
(void) llvm::createLoopUnswitchPass();
|
||||
(void) llvm::createLoopIdiomPass();
|
||||
(void) llvm::createLoopRotatePass();
|
||||
(void) llvm::createLowerExpectIntrinsicPass();
|
||||
(void) llvm::createLowerInvokePass();
|
||||
(void) llvm::createLowerSetJmpPass();
|
||||
(void) llvm::createLowerSwitchPass();
|
||||
(void) llvm::createNoAAPass();
|
||||
(void) llvm::createNoProfileInfoPass();
|
||||
(void) llvm::createObjCARCAliasAnalysisPass();
|
||||
(void) llvm::createObjCARCExpandPass();
|
||||
(void) llvm::createObjCARCContractPass();
|
||||
(void) llvm::createObjCARCOptPass();
|
||||
(void) llvm::createProfileEstimatorPass();
|
||||
(void) llvm::createProfileVerifierPass();
|
||||
(void) llvm::createPathProfileVerifierPass();
|
||||
|
@ -37,6 +37,18 @@ namespace llvm {
|
||||
//===------------------------------------------------------------------===//
|
||||
// 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
|
||||
/// .subsections_via_symbols directive.
|
||||
@ -284,6 +296,10 @@ namespace llvm {
|
||||
// use EmitLabelOffsetDifference.
|
||||
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 -----------------------------------===//
|
||||
|
||||
const char *const *AsmTransCBE; // Defaults to empty
|
||||
@ -296,6 +312,21 @@ namespace llvm {
|
||||
static unsigned getSLEB128Size(int 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; }
|
||||
|
||||
// Data directive accessors.
|
||||
@ -475,6 +506,9 @@ namespace llvm {
|
||||
bool doesDwarfUsesLabelOffsetForRanges() const {
|
||||
return DwarfUsesLabelOffsetForRanges;
|
||||
}
|
||||
bool useDwarfRegNumForCFI() const {
|
||||
return DwarfRegNumForCFI;
|
||||
}
|
||||
const char *const *getAsmCBE() const {
|
||||
return AsmTransCBE;
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ namespace llvm {
|
||||
class MCContext {
|
||||
MCContext(const MCContext&); // DO NOT IMPLEMENT
|
||||
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
|
||||
private:
|
||||
|
||||
/// The MCAsmInfo for this target.
|
||||
const MCAsmInfo &MAI;
|
||||
@ -52,7 +55,7 @@ namespace llvm {
|
||||
BumpPtrAllocator Allocator;
|
||||
|
||||
/// Symbols - Bindings of names to symbols.
|
||||
StringMap<MCSymbol*, BumpPtrAllocator&> Symbols;
|
||||
SymbolTable Symbols;
|
||||
|
||||
/// UsedNames - Keeps tracks of names that were used both for used declared
|
||||
/// and artificial symbols.
|
||||
@ -142,6 +145,14 @@ namespace llvm {
|
||||
/// LookupSymbol - Get the symbol for \p Name, or null.
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
|
||||
//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_TARGETINSTRDESC_H
|
||||
#define LLVM_TARGET_TARGETINSTRDESC_H
|
||||
#ifndef LLVM_MC_MCINSTRDESC_H
|
||||
#define LLVM_MC_MCINSTRDESC_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetRegisterClass;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Machine Operand Flags and Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace TOI {
|
||||
namespace MCOI {
|
||||
// Operand constraints
|
||||
enum OperandConstraint {
|
||||
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
|
||||
/// 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.
|
||||
enum OperandFlags {
|
||||
LookupPtrRegClass = 0,
|
||||
Predicate,
|
||||
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.
|
||||
///
|
||||
class TargetOperandInfo {
|
||||
class MCOperandInfo {
|
||||
public:
|
||||
/// RegClass - This specifies the register class enumeration of the operand
|
||||
/// if the operand is a register. If isLookupPtrRegClass is set, then this is
|
||||
/// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
|
||||
/// get a dynamic register class.
|
||||
///
|
||||
/// NOTE: This member should be considered to be private, all access should go
|
||||
/// through "getRegClass(TRI)" below.
|
||||
short RegClass;
|
||||
|
||||
/// Flags - These are flags from the TOI::OperandFlags enum.
|
||||
/// Flags - These are flags from the MCOI::OperandFlags enum.
|
||||
unsigned short Flags;
|
||||
|
||||
/// 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).
|
||||
unsigned Constraints;
|
||||
|
||||
/// OperandType - Information about the type of the operand.
|
||||
MCOI::OperandType OperandType;
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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.
|
||||
///
|
||||
bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); }
|
||||
bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
|
||||
};
|
||||
|
||||
|
||||
@ -89,11 +89,11 @@ class TargetOperandInfo {
|
||||
// Machine Instruction Flags and Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// TargetInstrDesc flags - These should be considered private to the
|
||||
/// implementation of the TargetInstrDesc class. Clients should use the
|
||||
/// predicate methods on TargetInstrDesc, not use these directly. These
|
||||
/// all correspond to bitfields in the TargetInstrDesc::Flags field.
|
||||
namespace TID {
|
||||
/// MCInstrDesc flags - These should be considered private to the
|
||||
/// implementation of the MCInstrDesc class. Clients should use the predicate
|
||||
/// methods on MCInstrDesc, not use these directly. These all correspond to
|
||||
/// bitfields in the MCInstrDesc::Flags field.
|
||||
namespace MCID {
|
||||
enum {
|
||||
Variadic = 0,
|
||||
HasOptionalDef,
|
||||
@ -123,29 +123,29 @@ namespace TID {
|
||||
};
|
||||
}
|
||||
|
||||
/// TargetInstrDesc - Describe properties that are true of each
|
||||
/// instruction in the target description file. This captures information about
|
||||
/// side effects, register use and many other things. There is one instance of
|
||||
/// this struct for each target instruction class, and the MachineInstr class
|
||||
/// points to this struct directly to describe itself.
|
||||
class TargetInstrDesc {
|
||||
/// MCInstrDesc - Describe properties that are true of each instruction in the
|
||||
/// target description file. This captures information about side effects,
|
||||
/// register use and many other things. There is one instance of this struct
|
||||
/// for each target instruction class, and the MachineInstr class points to
|
||||
/// this struct directly to describe itself.
|
||||
class MCInstrDesc {
|
||||
public:
|
||||
unsigned short Opcode; // The opcode number
|
||||
unsigned short NumOperands; // Num of args (may be more if variable_ops)
|
||||
unsigned short NumDefs; // Num of args that are definitions
|
||||
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
|
||||
unsigned Flags; // Flags identifying machine instr class
|
||||
uint64_t TSFlags; // Target Specific Flag values
|
||||
const unsigned *ImplicitUses; // Registers implicitly read by this instr
|
||||
const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
|
||||
const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered"
|
||||
const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands
|
||||
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
|
||||
|
||||
/// getOperandConstraint - Returns the value of the specific constraint if
|
||||
/// it is set. Returns -1 if it is not set.
|
||||
int getOperandConstraint(unsigned OpNum,
|
||||
TOI::OperandConstraint Constraint) const {
|
||||
MCOI::OperandConstraint Constraint) const {
|
||||
if (OpNum < NumOperands &&
|
||||
(OpInfo[OpNum].Constraints & (1 << Constraint))) {
|
||||
unsigned Pos = 16 + Constraint * 4;
|
||||
@ -154,12 +154,6 @@ class TargetInstrDesc {
|
||||
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.
|
||||
unsigned getOpcode() const {
|
||||
return Opcode;
|
||||
@ -193,13 +187,13 @@ class TargetInstrDesc {
|
||||
/// operands but before the implicit definitions and uses (if any are
|
||||
/// present).
|
||||
bool isVariadic() const {
|
||||
return Flags & (1 << TID::Variadic);
|
||||
return Flags & (1 << MCID::Variadic);
|
||||
}
|
||||
|
||||
/// hasOptionalDef - Set if this instruction has an optional definition, e.g.
|
||||
/// ARM instructions which can set condition code if 's' bit is set.
|
||||
bool hasOptionalDef() const {
|
||||
return Flags & (1 << TID::HasOptionalDef);
|
||||
return Flags & (1 << MCID::HasOptionalDef);
|
||||
}
|
||||
|
||||
/// getImplicitUses - Return a list of registers that are potentially
|
||||
@ -214,7 +208,7 @@ class TargetInstrDesc {
|
||||
const unsigned *getImplicitUses() const {
|
||||
return ImplicitUses;
|
||||
}
|
||||
|
||||
|
||||
/// getNumImplicitUses - Return the number of implicit uses this instruction
|
||||
/// has.
|
||||
unsigned getNumImplicitUses() const {
|
||||
@ -223,8 +217,7 @@ class TargetInstrDesc {
|
||||
for (; ImplicitUses[i]; ++i) /*empty*/;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// getImplicitDefs - Return a list of registers that are potentially
|
||||
/// written by any instance of this machine instruction. For example, on X86,
|
||||
/// many instructions implicitly set the flags register. In this case, they
|
||||
@ -266,17 +259,6 @@ class TargetInstrDesc {
|
||||
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
|
||||
/// scheduling class is an index into the InstrItineraryData table. This
|
||||
/// returns zero if there is no known scheduling information for the
|
||||
@ -286,19 +268,25 @@ class TargetInstrDesc {
|
||||
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 {
|
||||
return Flags & (1 << TID::Return);
|
||||
return Flags & (1 << MCID::Return);
|
||||
}
|
||||
|
||||
bool isCall() const {
|
||||
return Flags & (1 << TID::Call);
|
||||
return Flags & (1 << MCID::Call);
|
||||
}
|
||||
|
||||
/// isBarrier - Returns true if the specified instruction stops control flow
|
||||
/// from executing the instruction immediately following it. Examples include
|
||||
/// unconditional branches and return instructions.
|
||||
bool isBarrier() const {
|
||||
return Flags & (1 << TID::Barrier);
|
||||
return Flags & (1 << MCID::Barrier);
|
||||
}
|
||||
|
||||
/// isTerminator - Returns true if this instruction part of the terminator for
|
||||
@ -308,7 +296,7 @@ class TargetInstrDesc {
|
||||
/// Various passes use this to insert code into the bottom of a basic block,
|
||||
/// but before control flow occurs.
|
||||
bool isTerminator() const {
|
||||
return Flags & (1 << TID::Terminator);
|
||||
return Flags & (1 << MCID::Terminator);
|
||||
}
|
||||
|
||||
/// isBranch - Returns true if this is a conditional, unconditional, or
|
||||
@ -316,13 +304,13 @@ class TargetInstrDesc {
|
||||
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
|
||||
/// get more information.
|
||||
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
|
||||
/// branch through a register.
|
||||
bool isIndirectBranch() const {
|
||||
return Flags & (1 << TID::IndirectBranch);
|
||||
return Flags & (1 << MCID::IndirectBranch);
|
||||
}
|
||||
|
||||
/// isConditionalBranch - Return true if this is a branch which may fall
|
||||
@ -346,37 +334,37 @@ class TargetInstrDesc {
|
||||
/// values. There are various methods in TargetInstrInfo that can be used to
|
||||
/// control and modify the predicate in this instruction.
|
||||
bool isPredicable() const {
|
||||
return Flags & (1 << TID::Predicable);
|
||||
return Flags & (1 << MCID::Predicable);
|
||||
}
|
||||
|
||||
/// isCompare - Return true if this instruction is a comparison.
|
||||
bool isCompare() const {
|
||||
return Flags & (1 << TID::Compare);
|
||||
return Flags & (1 << MCID::Compare);
|
||||
}
|
||||
|
||||
/// isMoveImmediate - Return true if this instruction is a move immediate
|
||||
/// (including conditional moves) instruction.
|
||||
bool isMoveImmediate() const {
|
||||
return Flags & (1 << TID::MoveImm);
|
||||
return Flags & (1 << MCID::MoveImm);
|
||||
}
|
||||
|
||||
/// isBitcast - Return true if this instruction is a bitcast instruction.
|
||||
///
|
||||
bool isBitcast() const {
|
||||
return Flags & (1 << TID::Bitcast);
|
||||
return Flags & (1 << MCID::Bitcast);
|
||||
}
|
||||
|
||||
/// isNotDuplicable - Return true if this instruction cannot be safely
|
||||
/// duplicated. For example, if the instruction has a unique labels attached
|
||||
/// to it, duplicating it would cause multiple definition errors.
|
||||
bool isNotDuplicable() const {
|
||||
return Flags & (1 << TID::NotDuplicable);
|
||||
return Flags & (1 << MCID::NotDuplicable);
|
||||
}
|
||||
|
||||
/// hasDelaySlot - Returns true if the specified instruction has a delay slot
|
||||
/// which must be filled by the code generator.
|
||||
bool hasDelaySlot() const {
|
||||
return Flags & (1 << TID::DelaySlot);
|
||||
return Flags & (1 << MCID::DelaySlot);
|
||||
}
|
||||
|
||||
/// canFoldAsLoad - Return true for instructions that can be folded as
|
||||
@ -388,7 +376,7 @@ class TargetInstrDesc {
|
||||
/// This should only be set on instructions that return a value in their
|
||||
/// only virtual register definition.
|
||||
bool canFoldAsLoad() const {
|
||||
return Flags & (1 << TID::FoldableAsLoad);
|
||||
return Flags & (1 << MCID::FoldableAsLoad);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -399,7 +387,7 @@ class TargetInstrDesc {
|
||||
/// Instructions with this flag set are not necessarily simple load
|
||||
/// instructions, they may load a value and modify it, for example.
|
||||
bool mayLoad() const {
|
||||
return Flags & (1 << TID::MayLoad);
|
||||
return Flags & (1 << MCID::MayLoad);
|
||||
}
|
||||
|
||||
|
||||
@ -408,7 +396,7 @@ class TargetInstrDesc {
|
||||
/// instructions, they may store a modified value based on their operands, or
|
||||
/// may not actually modify anything, for example.
|
||||
bool mayStore() const {
|
||||
return Flags & (1 << TID::MayStore);
|
||||
return Flags & (1 << MCID::MayStore);
|
||||
}
|
||||
|
||||
/// hasUnmodeledSideEffects - Return true if this instruction has side
|
||||
@ -425,7 +413,7 @@ class TargetInstrDesc {
|
||||
/// LLVM, etc.
|
||||
///
|
||||
bool hasUnmodeledSideEffects() const {
|
||||
return Flags & (1 << TID::UnmodeledSideEffects);
|
||||
return Flags & (1 << MCID::UnmodeledSideEffects);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -443,7 +431,7 @@ class TargetInstrDesc {
|
||||
/// Also note that some instructions require non-trivial modification to
|
||||
/// commute them.
|
||||
bool isCommutable() const {
|
||||
return Flags & (1 << TID::Commutable);
|
||||
return Flags & (1 << MCID::Commutable);
|
||||
}
|
||||
|
||||
/// isConvertibleTo3Addr - Return true if this is a 2-address instruction
|
||||
@ -461,7 +449,7 @@ class TargetInstrDesc {
|
||||
/// instruction (e.g. shl reg, 4 on x86).
|
||||
///
|
||||
bool isConvertibleTo3Addr() const {
|
||||
return Flags & (1 << TID::ConvertibleTo3Addr);
|
||||
return Flags & (1 << MCID::ConvertibleTo3Addr);
|
||||
}
|
||||
|
||||
/// usesCustomInsertionHook - Return true if this instruction requires
|
||||
@ -473,7 +461,7 @@ class TargetInstrDesc {
|
||||
/// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
|
||||
/// is used to insert this into the MachineBasicBlock.
|
||||
bool usesCustomInsertionHook() const {
|
||||
return Flags & (1 << TID::UsesCustomInserter);
|
||||
return Flags & (1 << MCID::UsesCustomInserter);
|
||||
}
|
||||
|
||||
/// isRematerializable - Returns true if this instruction is a candidate for
|
||||
@ -481,7 +469,7 @@ class TargetInstrDesc {
|
||||
/// flag is set, the isReallyTriviallyReMaterializable() method is called to
|
||||
/// verify the instruction is really rematable.
|
||||
bool isRematerializable() const {
|
||||
return Flags & (1 << TID::Rematerializable);
|
||||
return Flags & (1 << MCID::Rematerializable);
|
||||
}
|
||||
|
||||
/// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
|
||||
@ -491,7 +479,7 @@ class TargetInstrDesc {
|
||||
/// 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.
|
||||
bool isAsCheapAsAMove() const {
|
||||
return Flags & (1 << TID::CheapAsAMove);
|
||||
return Flags & (1 << MCID::CheapAsAMove);
|
||||
}
|
||||
|
||||
/// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
|
||||
@ -501,7 +489,7 @@ class TargetInstrDesc {
|
||||
/// Post-register allocation passes should not attempt to change allocations
|
||||
/// for sources of instructions with this flag.
|
||||
bool hasExtraSrcRegAllocReq() const {
|
||||
return Flags & (1 << TID::ExtraSrcRegAllocReq);
|
||||
return Flags & (1 << MCID::ExtraSrcRegAllocReq);
|
||||
}
|
||||
|
||||
/// hasExtraDefRegAllocReq - Returns true if this instruction def operands
|
||||
@ -511,7 +499,7 @@ class TargetInstrDesc {
|
||||
/// Post-register allocation passes should not attempt to change allocations
|
||||
/// for definitions of instructions with this flag.
|
||||
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
|
||||
//
|
||||
@ -13,8 +13,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
|
||||
#define LLVM_TARGET_TARGETINSTRITINERARIES_H
|
||||
#ifndef LLVM_MC_MCINSTRITINERARIES_H
|
||||
#define LLVM_MC_MCINSTRITINERARIES_H
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -10,11 +10,20 @@
|
||||
#ifndef 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/Object/MachOFormat.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCSectionData;
|
||||
class MachObjectWriter;
|
||||
|
||||
class MCMachObjectTargetWriter {
|
||||
const unsigned Is64Bit : 1;
|
||||
const uint32_t CPUType;
|
||||
@ -48,8 +57,191 @@ class MCMachObjectTargetWriter {
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @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.
|
||||
///
|
||||
/// This routine takes ownership of the target writer subclass.
|
||||
|
@ -73,7 +73,8 @@ class MCObjectStreamer : public MCStreamer {
|
||||
virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
|
||||
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
|
||||
const MCSymbol *LastLabel,
|
||||
const MCSymbol *Label);
|
||||
const MCSymbol *Label,
|
||||
unsigned PointerSize);
|
||||
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
|
||||
const MCSymbol *Label);
|
||||
virtual void Finish();
|
||||
|
@ -28,10 +28,20 @@ class MCParsedAsmOperand {
|
||||
/// getEndLoc - Get the location of the last token of this operand.
|
||||
virtual SMLoc getEndLoc() const = 0;
|
||||
|
||||
/// dump - Print a debug representation of the operand to the given stream.
|
||||
virtual void dump(raw_ostream &OS) const = 0;
|
||||
/// print - Print a debug representation of the operand to the given stream.
|
||||
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.
|
||||
|
||||
#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,
|
||||
const MCSymbol *LastLabel,
|
||||
const MCSymbol *Label) = 0;
|
||||
const MCSymbol *Label,
|
||||
unsigned PointerSize) = 0;
|
||||
|
||||
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
|
||||
const MCSymbol *Label) {
|
||||
@ -547,6 +548,9 @@ namespace llvm {
|
||||
///
|
||||
/// \param ShowInst - Whether to show the MCInst representation inline with
|
||||
/// 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,
|
||||
bool isVerboseAsm,
|
||||
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
|
||||
//
|
||||
@ -15,17 +15,16 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
|
||||
#define LLVM_TARGET_SUBTARGETFEATURE_H
|
||||
#ifndef LLVM_MC_SUBTARGETFEATURE_H
|
||||
#define LLVM_MC_SUBTARGETFEATURE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
class StringRef;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
@ -75,32 +74,30 @@ struct SubtargetInfoKV {
|
||||
class SubtargetFeatures {
|
||||
std::vector<std::string> Features; // Subtarget features as a vector
|
||||
public:
|
||||
explicit SubtargetFeatures(const std::string &Initial = std::string());
|
||||
explicit SubtargetFeatures(const StringRef Initial = "");
|
||||
|
||||
/// Features string accessors.
|
||||
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.
|
||||
void AddFeature(const std::string &String, bool IsEnabled = true);
|
||||
void AddFeature(const StringRef String, bool IsEnabled = true);
|
||||
|
||||
/// Get feature bits.
|
||||
uint64_t getBits(const SubtargetFeatureKV *CPUTable,
|
||||
size_t CPUTableSize,
|
||||
const SubtargetFeatureKV *FeatureTable,
|
||||
/// ToggleFeature - Toggle a feature and returns the newly updated feature
|
||||
/// bits.
|
||||
uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
|
||||
const SubtargetFeatureKV *FeatureTable,
|
||||
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
|
||||
void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
|
||||
/// Get scheduling itinerary of a CPU.
|
||||
void *getItinerary(const StringRef CPU,
|
||||
const SubtargetInfoKV *Table, size_t TableSize);
|
||||
|
||||
/// Print feature string.
|
||||
void print(raw_ostream &OS) const;
|
||||
@ -110,8 +107,7 @@ class SubtargetFeatures {
|
||||
|
||||
/// Retrieve a formatted string of the default features for the specified
|
||||
/// target triple.
|
||||
void getDefaultSubtargetFeatures(const std::string &CPU,
|
||||
const Triple& Triple);
|
||||
void getDefaultSubtargetFeatures(const Triple& Triple);
|
||||
};
|
||||
|
||||
} // End namespace llvm
|
@ -28,6 +28,10 @@ namespace llvm {
|
||||
class FunctionType;
|
||||
class GVMaterializer;
|
||||
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>
|
||||
: public SymbolTableListTraits<Function, Module> {
|
||||
@ -145,7 +149,6 @@ class Module {
|
||||
NamedMDListType NamedMDList; ///< The named metadata in the module
|
||||
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
|
||||
ValueSymbolTable *ValSymTab; ///< Symbol table for values
|
||||
TypeSymbolTable *TypeSymTab; ///< Symbol table for types
|
||||
OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues
|
||||
std::string ModuleID; ///< Human readable identifier for the module
|
||||
std::string TargetTriple; ///< Platform target triple Module compiled on
|
||||
@ -231,7 +234,7 @@ class Module {
|
||||
/// @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
|
||||
/// if a global with the specified name is not found.
|
||||
GlobalValue *getNamedValue(StringRef Name) const;
|
||||
@ -244,6 +247,18 @@ class Module {
|
||||
/// custom metadata IDs registered in this LLVMContext.
|
||||
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
|
||||
/// @{
|
||||
@ -296,7 +311,7 @@ class Module {
|
||||
GlobalVariable *getGlobalVariable(StringRef Name,
|
||||
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
|
||||
/// with the specified name is not found.
|
||||
GlobalVariable *getNamedGlobal(StringRef Name) const {
|
||||
@ -316,7 +331,7 @@ class Module {
|
||||
/// @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
|
||||
/// with the specified name is not found.
|
||||
GlobalAlias *getNamedAlias(StringRef Name) const;
|
||||
@ -325,12 +340,12 @@ class Module {
|
||||
/// @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 is not found.
|
||||
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
|
||||
/// NamedMDNode with the specified name is not found.
|
||||
NamedMDNode *getOrInsertNamedMetadata(StringRef Name);
|
||||
@ -339,23 +354,6 @@ class Module {
|
||||
/// and delete it.
|
||||
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
|
||||
/// @{
|
||||
@ -429,41 +427,26 @@ class Module {
|
||||
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
|
||||
/// Get the Module's symbol table of global variable and function identifiers.
|
||||
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
|
||||
/// @{
|
||||
|
||||
/// Get an iterator to the first global variable
|
||||
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(); }
|
||||
/// Get an iterator to the last global variable
|
||||
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(); }
|
||||
/// Determine if the list of globals is empty.
|
||||
bool global_empty() const { return GlobalList.empty(); }
|
||||
|
||||
/// @}
|
||||
/// @name Function Iteration
|
||||
/// @{
|
||||
|
||||
/// Get an iterator to the first function.
|
||||
iterator begin() { return FunctionList.begin(); }
|
||||
/// Get a constant iterator to the first function.
|
||||
const_iterator begin() const { return FunctionList.begin(); }
|
||||
/// Get an iterator to the last function.
|
||||
iterator end () { return FunctionList.end(); }
|
||||
/// Get a constant iterator to the last function.
|
||||
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(); }
|
||||
/// Determine if the list of functions is empty.
|
||||
bool empty() const { return FunctionList.empty(); }
|
||||
|
||||
/// @}
|
||||
@ -487,17 +470,11 @@ class Module {
|
||||
/// @name Alias Iteration
|
||||
/// @{
|
||||
|
||||
/// Get an iterator to the first alias.
|
||||
alias_iterator alias_begin() { return AliasList.begin(); }
|
||||
/// Get a constant iterator to the first alias.
|
||||
const_alias_iterator alias_begin() const { return AliasList.begin(); }
|
||||
/// Get an iterator to the last alias.
|
||||
alias_iterator alias_end () { return AliasList.end(); }
|
||||
/// Get a constant iterator to the last alias.
|
||||
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(); }
|
||||
/// Determine if the list of aliases is empty.
|
||||
bool alias_empty() const { return AliasList.empty(); }
|
||||
|
||||
|
||||
@ -505,24 +482,17 @@ class Module {
|
||||
/// @name Named Metadata Iteration
|
||||
/// @{
|
||||
|
||||
/// Get an iterator to the first named metadata.
|
||||
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 {
|
||||
return NamedMDList.begin();
|
||||
}
|
||||
|
||||
/// Get an iterator to the last named metadata.
|
||||
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 {
|
||||
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(); }
|
||||
/// Determine if the list of named metadata is empty.
|
||||
bool named_metadata_empty() const { return NamedMDList.empty(); }
|
||||
|
||||
|
||||
@ -530,11 +500,13 @@ class Module {
|
||||
/// @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;
|
||||
|
||||
/// Dump the module to stderr (for debugging).
|
||||
void dump() const;
|
||||
|
||||
/// 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
|
||||
/// 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
|
||||
#define LLVM_OBJECT_OBJECT_FILE_H
|
||||
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
class StringRef;
|
||||
|
||||
namespace object {
|
||||
|
||||
class ObjectFile;
|
||||
@ -31,7 +30,7 @@ union DataRefImpl {
|
||||
struct {
|
||||
uint32_t a, b;
|
||||
} d;
|
||||
intptr_t p;
|
||||
uintptr_t p;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
/// the list of symbols in the object file.
|
||||
class SymbolRef {
|
||||
friend class SectionRef;
|
||||
DataRefImpl SymbolPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
SymbolRef() : OwningObject(NULL) {
|
||||
std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl));
|
||||
}
|
||||
|
||||
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const SymbolRef &Other) const;
|
||||
|
||||
SymbolRef getNext() const;
|
||||
error_code getNext(SymbolRef &Result) const;
|
||||
|
||||
StringRef getName() const;
|
||||
uint64_t getAddress() const;
|
||||
uint64_t getSize() const;
|
||||
error_code getName(StringRef &Result) const;
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getSize(uint64_t &Result) const;
|
||||
|
||||
/// Returns the ascii char that should be displayed in a symbol table dump via
|
||||
/// 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
|
||||
/// 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
|
||||
/// the list of sections in the object file.
|
||||
class SectionRef {
|
||||
friend class SymbolRef;
|
||||
DataRefImpl SectionPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
SectionRef() : OwningObject(NULL) {
|
||||
std::memset(&SectionPimpl, 0, sizeof(SectionPimpl));
|
||||
}
|
||||
|
||||
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const SectionRef &Other) const;
|
||||
|
||||
SectionRef getNext() const;
|
||||
error_code getNext(SectionRef &Result) const;
|
||||
|
||||
StringRef getName() const;
|
||||
uint64_t getAddress() const;
|
||||
uint64_t getSize() const;
|
||||
StringRef getContents() const;
|
||||
error_code getName(StringRef &Result) const;
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getSize(uint64_t &Result) const;
|
||||
error_code getContents(StringRef &Result) const;
|
||||
|
||||
// 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;
|
||||
@ -93,38 +120,44 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
|
||||
/// ObjectFile - This class is the base class for all object file types.
|
||||
/// Concrete instances of this object are created by createObjectFile, which
|
||||
/// figure out which type to create.
|
||||
class ObjectFile {
|
||||
class ObjectFile : public Binary {
|
||||
private:
|
||||
ObjectFile(); // = delete
|
||||
ObjectFile(const ObjectFile &other); // = delete
|
||||
|
||||
protected:
|
||||
MemoryBuffer *MapFile;
|
||||
const uint8_t *base;
|
||||
ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
|
||||
|
||||
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
|
||||
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
|
||||
// entry in the memory mapped object file. SymbolPimpl cannot contain any
|
||||
// virtual functions because then it could not point into the memory mapped
|
||||
// file.
|
||||
//
|
||||
// Implementations assume that the DataRefImpl is valid and has not been
|
||||
// modified externally. It's UB otherwise.
|
||||
friend class SymbolRef;
|
||||
virtual SymbolRef getSymbolNext(DataRefImpl Symb) const = 0;
|
||||
virtual StringRef getSymbolName(DataRefImpl Symb) const = 0;
|
||||
virtual uint64_t getSymbolAddress(DataRefImpl Symb) const = 0;
|
||||
virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
|
||||
virtual char getSymbolNMTypeChar(DataRefImpl Symb) const = 0;
|
||||
virtual bool isSymbolInternal(DataRefImpl Symb) const = 0;
|
||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
|
||||
virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0;
|
||||
|
||||
// Same as above for SectionRef.
|
||||
friend class SectionRef;
|
||||
virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0;
|
||||
virtual StringRef getSectionName(DataRefImpl Sec) const = 0;
|
||||
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
|
||||
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
|
||||
virtual StringRef getSectionContents(DataRefImpl Sec) const = 0;
|
||||
virtual bool isSectionText(DataRefImpl Sec) const = 0;
|
||||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
|
||||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
|
||||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
|
||||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
|
||||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)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:
|
||||
@ -139,6 +172,10 @@ class ObjectFile {
|
||||
return &Current;
|
||||
}
|
||||
|
||||
const content_type &operator*() const {
|
||||
return Current;
|
||||
}
|
||||
|
||||
bool operator==(const content_iterator &other) const {
|
||||
return Current == other.Current;
|
||||
}
|
||||
@ -147,8 +184,12 @@ class ObjectFile {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
content_iterator& operator++() { // Preincrement
|
||||
Current = Current.getNext();
|
||||
content_iterator& increment(error_code &err) {
|
||||
content_type next;
|
||||
if (error_code ec = Current.getNext(next))
|
||||
err = ec;
|
||||
else
|
||||
Current = next;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@ -156,8 +197,6 @@ class ObjectFile {
|
||||
typedef content_iterator<SymbolRef> symbol_iterator;
|
||||
typedef content_iterator<SectionRef> section_iterator;
|
||||
|
||||
virtual ~ObjectFile();
|
||||
|
||||
virtual symbol_iterator begin_symbols() const = 0;
|
||||
virtual symbol_iterator end_symbols() const = 0;
|
||||
|
||||
@ -171,8 +210,6 @@ class ObjectFile {
|
||||
virtual StringRef getFileFormatName() const = 0;
|
||||
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
|
||||
|
||||
StringRef getFilename() const;
|
||||
|
||||
/// @returns Pointer to ObjectFile subclass to handle this type of object.
|
||||
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
|
||||
/// return true.
|
||||
@ -180,12 +217,16 @@ class ObjectFile {
|
||||
static ObjectFile *createObjectFile(StringRef ObjectPath);
|
||||
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 *createELFObjectFile(MemoryBuffer *Object);
|
||||
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
|
||||
static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object);
|
||||
static ObjectFile *createLibObjectFile(MemoryBuffer *Object);
|
||||
};
|
||||
|
||||
// Inline function definitions.
|
||||
@ -197,28 +238,28 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const {
|
||||
return SymbolPimpl == Other.SymbolPimpl;
|
||||
}
|
||||
|
||||
inline SymbolRef SymbolRef::getNext() const {
|
||||
return OwningObject->getSymbolNext(SymbolPimpl);
|
||||
inline error_code SymbolRef::getNext(SymbolRef &Result) const {
|
||||
return OwningObject->getSymbolNext(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline StringRef SymbolRef::getName() const {
|
||||
return OwningObject->getSymbolName(SymbolPimpl);
|
||||
inline error_code SymbolRef::getName(StringRef &Result) const {
|
||||
return OwningObject->getSymbolName(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline uint64_t SymbolRef::getAddress() const {
|
||||
return OwningObject->getSymbolAddress(SymbolPimpl);
|
||||
inline error_code SymbolRef::getAddress(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolAddress(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline uint64_t SymbolRef::getSize() const {
|
||||
return OwningObject->getSymbolSize(SymbolPimpl);
|
||||
inline error_code SymbolRef::getSize(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolSize(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline char SymbolRef::getNMTypeChar() const {
|
||||
return OwningObject->getSymbolNMTypeChar(SymbolPimpl);
|
||||
inline error_code SymbolRef::getNMTypeChar(char &Result) const {
|
||||
return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline bool SymbolRef::isInternal() const {
|
||||
return OwningObject->isSymbolInternal(SymbolPimpl);
|
||||
inline error_code SymbolRef::isInternal(bool &Result) const {
|
||||
return OwningObject->isSymbolInternal(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
|
||||
@ -232,28 +273,33 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
|
||||
return SectionPimpl == Other.SectionPimpl;
|
||||
}
|
||||
|
||||
inline SectionRef SectionRef::getNext() const {
|
||||
return OwningObject->getSectionNext(SectionPimpl);
|
||||
inline error_code SectionRef::getNext(SectionRef &Result) const {
|
||||
return OwningObject->getSectionNext(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline StringRef SectionRef::getName() const {
|
||||
return OwningObject->getSectionName(SectionPimpl);
|
||||
inline error_code SectionRef::getName(StringRef &Result) const {
|
||||
return OwningObject->getSectionName(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline uint64_t SectionRef::getAddress() const {
|
||||
return OwningObject->getSectionAddress(SectionPimpl);
|
||||
inline error_code SectionRef::getAddress(uint64_t &Result) const {
|
||||
return OwningObject->getSectionAddress(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline uint64_t SectionRef::getSize() const {
|
||||
return OwningObject->getSectionSize(SectionPimpl);
|
||||
inline error_code SectionRef::getSize(uint64_t &Result) const {
|
||||
return OwningObject->getSectionSize(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline StringRef SectionRef::getContents() const {
|
||||
return OwningObject->getSectionContents(SectionPimpl);
|
||||
inline error_code SectionRef::getContents(StringRef &Result) const {
|
||||
return OwningObject->getSectionContents(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline bool SectionRef::isText() const {
|
||||
return OwningObject->isSectionText(SectionPimpl);
|
||||
inline error_code SectionRef::isText(bool &Result) const {
|
||||
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
|
||||
|
@ -19,15 +19,9 @@
|
||||
namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
class BranchProbabilityInfo;
|
||||
class MachineBranchProbabilityInfo;
|
||||
class MachineBasicBlock;
|
||||
|
||||
// This class represents Branch Probability as a non-negative fraction.
|
||||
class BranchProbability {
|
||||
friend class BranchProbabilityInfo;
|
||||
friend class MachineBranchProbabilityInfo;
|
||||
friend class MachineBasicBlock;
|
||||
|
||||
// Numerator
|
||||
uint32_t N;
|
||||
@ -35,9 +29,17 @@ class BranchProbability {
|
||||
// Denominator
|
||||
uint32_t D;
|
||||
|
||||
public:
|
||||
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;
|
||||
|
||||
void dump() const;
|
||||
|
@ -33,7 +33,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
|
||||
USE_iterator It;
|
||||
|
||||
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))
|
||||
++It;
|
||||
}
|
||||
@ -109,11 +109,18 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
// TODO: This can be random access iterator, only operator[] missing.
|
||||
|
||||
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
|
||||
assert(T && "getTerminator returned null!");
|
||||
}
|
||||
inline SuccIterator(Term_ T, bool) // end iterator
|
||||
: Term(T), idx(Term->getNumSuccessors()) {
|
||||
assert(T && "getTerminator returned null!");
|
||||
: Term(T) {
|
||||
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) {
|
||||
@ -201,6 +208,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
|
||||
/// Get the source BB of this iterator.
|
||||
inline BB_ *getSource() {
|
||||
assert(Term && "Source not available, if basic block was malformed");
|
||||
return Term->getParent();
|
||||
}
|
||||
};
|
||||
|
@ -210,14 +210,14 @@ class ConstantFolder {
|
||||
return ConstantExpr::getShuffleVector(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx);
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getExtractValue(Agg, IdxList);
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx) const {
|
||||
return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx);
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getInsertValue(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,10 @@ namespace llvm {
|
||||
|
||||
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
|
||||
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.
|
||||
bool isUnknown() const { return ScopeIdx == 0; }
|
||||
|
||||
@ -94,6 +97,8 @@ namespace llvm {
|
||||
return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
|
||||
}
|
||||
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
|
||||
|
||||
void dump(const LLVMContext &Ctx) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
@ -487,11 +487,11 @@ enum {
|
||||
SHT_REL = 9, // Relocation entries; no explicit addends.
|
||||
SHT_SHLIB = 10, // Reserved.
|
||||
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_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
|
||||
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_HIOS = 0x6fffffff, // Highest operating system-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_SECTION = 3, // Symbol refers to a section
|
||||
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_LOPROC = 13, // Lowest 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_PLTREL = 20, // Type of relocation entry used for linking.
|
||||
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_BIND_NOW = 24, // Process all relocations before execution.
|
||||
DT_INIT_ARRAY = 25, // Pointer to array of initialization functions.
|
||||
|
@ -14,7 +14,6 @@
|
||||
#ifndef LLVM_SUPPORT_ENDIAN_H
|
||||
#define LLVM_SUPPORT_ENDIAN_H
|
||||
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/SwapByteOrder.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
@ -82,7 +82,7 @@ class IRBuilderBase {
|
||||
InsertPt = I;
|
||||
SetCurrentDebugLocation(I->getDebugLoc());
|
||||
}
|
||||
|
||||
|
||||
/// SetInsertPoint - This specifies that created instructions should be
|
||||
/// inserted at the specified point.
|
||||
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
|
||||
@ -90,6 +90,19 @@ class IRBuilderBase {
|
||||
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
|
||||
/// information.
|
||||
void SetCurrentDebugLocation(const DebugLoc &L) {
|
||||
@ -98,7 +111,7 @@ class IRBuilderBase {
|
||||
|
||||
/// getCurrentDebugLocation - Get location information used by debugging
|
||||
/// information.
|
||||
const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; }
|
||||
DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
|
||||
|
||||
/// SetInstDebugLocation - If this builder has a current debug location, set
|
||||
/// it on the specified instruction.
|
||||
@ -109,8 +122,8 @@ class IRBuilderBase {
|
||||
|
||||
/// getCurrentFunctionReturnType - Get the return type of the current function
|
||||
/// that we're emitting into.
|
||||
const Type *getCurrentFunctionReturnType() const;
|
||||
|
||||
Type *getCurrentFunctionReturnType() const;
|
||||
|
||||
/// InsertPoint - A saved insertion point.
|
||||
class InsertPoint {
|
||||
BasicBlock *Block;
|
||||
@ -198,7 +211,7 @@ class IRBuilderBase {
|
||||
ConstantInt *getInt64(uint64_t C) {
|
||||
return ConstantInt::get(getInt64Ty(), C);
|
||||
}
|
||||
|
||||
|
||||
/// getInt - Get a constant integer value.
|
||||
ConstantInt *getInt(const APInt &AI) {
|
||||
return ConstantInt::get(Context, AI);
|
||||
@ -209,46 +222,46 @@ class IRBuilderBase {
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// getInt1Ty - Fetch the type representing a single bit
|
||||
const IntegerType *getInt1Ty() {
|
||||
IntegerType *getInt1Ty() {
|
||||
return Type::getInt1Ty(Context);
|
||||
}
|
||||
|
||||
/// getInt8Ty - Fetch the type representing an 8-bit integer.
|
||||
const IntegerType *getInt8Ty() {
|
||||
IntegerType *getInt8Ty() {
|
||||
return Type::getInt8Ty(Context);
|
||||
}
|
||||
|
||||
/// getInt16Ty - Fetch the type representing a 16-bit integer.
|
||||
const IntegerType *getInt16Ty() {
|
||||
IntegerType *getInt16Ty() {
|
||||
return Type::getInt16Ty(Context);
|
||||
}
|
||||
|
||||
/// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
|
||||
const IntegerType *getInt32Ty() {
|
||||
IntegerType *getInt32Ty() {
|
||||
return Type::getInt32Ty(Context);
|
||||
}
|
||||
|
||||
/// getInt64Ty - Fetch the type representing a 64-bit integer.
|
||||
const IntegerType *getInt64Ty() {
|
||||
IntegerType *getInt64Ty() {
|
||||
return Type::getInt64Ty(Context);
|
||||
}
|
||||
|
||||
/// getFloatTy - Fetch the type representing a 32-bit floating point value.
|
||||
const Type *getFloatTy() {
|
||||
Type *getFloatTy() {
|
||||
return Type::getFloatTy(Context);
|
||||
}
|
||||
|
||||
/// getDoubleTy - Fetch the type representing a 64-bit floating point value.
|
||||
const Type *getDoubleTy() {
|
||||
Type *getDoubleTy() {
|
||||
return Type::getDoubleTy(Context);
|
||||
}
|
||||
|
||||
/// getVoidTy - Fetch the type representing void.
|
||||
const Type *getVoidTy() {
|
||||
Type *getVoidTy() {
|
||||
return Type::getVoidTy(Context);
|
||||
}
|
||||
|
||||
const PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
|
||||
PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
|
||||
return Type::getInt8PtrTy(Context, AddrSpace);
|
||||
}
|
||||
|
||||
@ -263,7 +276,7 @@ class IRBuilderBase {
|
||||
bool isVolatile = false, MDNode *TBAATag = 0) {
|
||||
return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
|
||||
}
|
||||
|
||||
|
||||
CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
|
||||
bool isVolatile = false, MDNode *TBAATag = 0);
|
||||
|
||||
@ -274,7 +287,7 @@ class IRBuilderBase {
|
||||
bool isVolatile = false, MDNode *TBAATag = 0) {
|
||||
return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
|
||||
}
|
||||
|
||||
|
||||
CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
|
||||
bool isVolatile = false, MDNode *TBAATag = 0);
|
||||
|
||||
@ -285,9 +298,9 @@ class IRBuilderBase {
|
||||
bool isVolatile = false, MDNode *TBAATag = 0) {
|
||||
return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
/// isn't i8* it will be converted.
|
||||
@ -341,7 +354,13 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
SetInsertPoint(IP);
|
||||
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)
|
||||
: IRBuilderBase(TheBB->getContext()), Folder(F) {
|
||||
SetInsertPoint(TheBB, IP);
|
||||
@ -430,34 +449,30 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
|
||||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest, const Twine &Name = "") {
|
||||
Value *Args[] = { 0 };
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
|
||||
Args), Name);
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
|
||||
ArrayRef<Value *>()),
|
||||
Name);
|
||||
}
|
||||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest, Value *Arg1,
|
||||
const Twine &Name = "") {
|
||||
Value *Args[] = { Arg1 };
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
|
||||
Args+1), Name);
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
|
||||
Name);
|
||||
}
|
||||
InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest, Value *Arg1,
|
||||
Value *Arg2, Value *Arg3,
|
||||
const Twine &Name = "") {
|
||||
Value *Args[] = { Arg1, Arg2, Arg3 };
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
|
||||
Args+3), Name);
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
|
||||
Name);
|
||||
}
|
||||
/// CreateInvoke - Create an invoke instruction.
|
||||
template<typename RandomAccessIterator>
|
||||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest,
|
||||
RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd,
|
||||
BasicBlock *UnwindDest, ArrayRef<Value *> Args,
|
||||
const Twine &Name = "") {
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
|
||||
ArgBegin, ArgEnd), Name);
|
||||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
|
||||
Name);
|
||||
}
|
||||
|
||||
UnwindInst *CreateUnwind() {
|
||||
@ -1107,33 +1122,27 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
|
||||
const Twine &Name = "") {
|
||||
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,
|
||||
const Twine &Name = "") {
|
||||
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,
|
||||
Value *Arg4, const Twine &Name = "") {
|
||||
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,
|
||||
Value *Arg4, Value *Arg5, const Twine &Name = "") {
|
||||
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 = "") {
|
||||
return Insert(CallInst::Create(Callee, Arg.begin(), Arg.end(), Name));
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
CallInst *CreateCall(Value *Callee, RandomAccessIterator ArgBegin,
|
||||
RandomAccessIterator ArgEnd, const Twine &Name = "") {
|
||||
return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name);
|
||||
return Insert(CallInst::Create(Callee, Args, Name));
|
||||
}
|
||||
|
||||
Value *CreateSelect(Value *C, Value *True, Value *False,
|
||||
@ -1175,43 +1184,21 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
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,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
return Insert(Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd-IdxBegin),
|
||||
Name);
|
||||
return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
|
||||
return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
|
||||
return Insert(ExtractValueInst::Create(Agg, Idxs), 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,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
if (Constant *ValC = dyn_cast<Constant>(Val))
|
||||
return Insert(Folder.CreateInsertValue(AggC, ValC, IdxBegin,
|
||||
IdxEnd - IdxBegin),
|
||||
Name);
|
||||
return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
|
||||
return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
|
||||
return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -1238,7 +1225,7 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
assert(LHS->getType() == RHS->getType() &&
|
||||
"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 *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
|
||||
Value *Difference = CreateSub(LHS_int, RHS_int);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#ifndef LLVM_SUPPORT_NOFOLDER_H
|
||||
#define LLVM_SUPPORT_NOFOLDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
|
||||
@ -269,15 +270,14 @@ class NoFolder {
|
||||
return new ShuffleVectorInst(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx);
|
||||
Instruction *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ExtractValueInst::Create(Agg, IdxList);
|
||||
}
|
||||
|
||||
Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return InsertValueInst::Create(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,7 +67,12 @@ class PassManagerBuilder {
|
||||
|
||||
/// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
|
||||
/// 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.
|
||||
@ -147,6 +152,7 @@ class PassManagerBuilder {
|
||||
FPM.add(createCFGSimplificationPass());
|
||||
FPM.add(createScalarReplAggregatesPass());
|
||||
FPM.add(createEarlyCSEPass());
|
||||
FPM.add(createLowerExpectIntrinsicPass());
|
||||
}
|
||||
|
||||
/// populateModulePassManager - This sets up the primary pass manager.
|
||||
@ -223,13 +229,16 @@ class PassManagerBuilder {
|
||||
MPM.add(createJumpThreadingPass()); // Thread jumps
|
||||
MPM.add(createCorrelatedValuePropagationPass());
|
||||
MPM.add(createDeadStoreEliminationPass()); // Delete dead stores
|
||||
|
||||
addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
|
||||
|
||||
MPM.add(createAggressiveDCEPass()); // Delete dead instructions
|
||||
MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
|
||||
MPM.add(createInstructionCombiningPass()); // Clean up after everything.
|
||||
|
||||
if (!DisableUnitAtATime) {
|
||||
// FIXME: We shouldn't bother with this anymore.
|
||||
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
|
||||
// late pass of GlobalDCE. It is capable of deleting dead cycles.
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/InstrTypes.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -226,14 +227,14 @@ class TargetFolder {
|
||||
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx));
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx) const {
|
||||
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx));
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include <limits.h>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -50,7 +51,7 @@ namespace llvm {
|
||||
/// namespace llvm {
|
||||
/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
|
||||
/// public:
|
||||
/// static const StructType *get(LLVMContext &Context) {
|
||||
/// static StructType *get(LLVMContext &Context) {
|
||||
/// // If you cache this result, be sure to cache it separately
|
||||
/// // for each LLVMContext.
|
||||
/// return StructType::get(
|
||||
@ -103,7 +104,7 @@ template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
|
||||
// Pointers
|
||||
template<typename T, bool cross> class TypeBuilder<T*, cross> {
|
||||
public:
|
||||
static const PointerType *get(LLVMContext &Context) {
|
||||
static PointerType *get(LLVMContext &Context) {
|
||||
return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
|
||||
}
|
||||
};
|
||||
@ -114,14 +115,14 @@ template<typename T, bool cross> class TypeBuilder<T&, cross> {};
|
||||
// Arrays
|
||||
template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
|
||||
public:
|
||||
static const ArrayType *get(LLVMContext &Context) {
|
||||
static ArrayType *get(LLVMContext &Context) {
|
||||
return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
|
||||
}
|
||||
};
|
||||
/// LLVM uses an array of length 0 to represent an unknown-length array.
|
||||
template<typename T, bool cross> class TypeBuilder<T[], cross> {
|
||||
public:
|
||||
static const ArrayType *get(LLVMContext &Context) {
|
||||
static ArrayType *get(LLVMContext &Context) {
|
||||
return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
|
||||
}
|
||||
};
|
||||
@ -151,7 +152,7 @@ template<typename T, bool cross> class TypeBuilder<T[], cross> {
|
||||
#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
|
||||
template<> class TypeBuilder<T, false> { \
|
||||
public: \
|
||||
static const IntegerType *get(LLVMContext &Context) { \
|
||||
static IntegerType *get(LLVMContext &Context) { \
|
||||
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>
|
||||
class TypeBuilder<types::i<num_bits>, cross> {
|
||||
public:
|
||||
static const IntegerType *get(LLVMContext &C) {
|
||||
static IntegerType *get(LLVMContext &C) {
|
||||
return IntegerType::get(C, num_bits);
|
||||
}
|
||||
};
|
||||
|
||||
template<> class TypeBuilder<float, false> {
|
||||
public:
|
||||
static const Type *get(LLVMContext& C) {
|
||||
static Type *get(LLVMContext& C) {
|
||||
return Type::getFloatTy(C);
|
||||
}
|
||||
};
|
||||
@ -195,7 +196,7 @@ template<> class TypeBuilder<float, true> {};
|
||||
|
||||
template<> class TypeBuilder<double, false> {
|
||||
public:
|
||||
static const Type *get(LLVMContext& C) {
|
||||
static Type *get(LLVMContext& C) {
|
||||
return Type::getDoubleTy(C);
|
||||
}
|
||||
};
|
||||
@ -203,32 +204,32 @@ template<> class TypeBuilder<double, true> {};
|
||||
|
||||
template<bool cross> class TypeBuilder<types::ieee_float, cross> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
public:
|
||||
static const Type *get(LLVMContext &C) {
|
||||
static Type *get(LLVMContext &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> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
|
||||
}
|
||||
};
|
||||
template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(1);
|
||||
params.push_back(TypeBuilder<A1, cross>::get(Context));
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(Context),
|
||||
@ -263,8 +264,8 @@ template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
|
||||
template<typename R, typename A1, typename A2, bool cross>
|
||||
class TypeBuilder<R(A1, A2), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(2);
|
||||
params.push_back(TypeBuilder<A1, cross>::get(Context));
|
||||
params.push_back(TypeBuilder<A2, cross>::get(Context));
|
||||
@ -275,8 +276,8 @@ class TypeBuilder<R(A1, A2), cross> {
|
||||
template<typename R, typename A1, typename A2, typename A3, bool cross>
|
||||
class TypeBuilder<R(A1, A2, A3), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(3);
|
||||
params.push_back(TypeBuilder<A1, 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>
|
||||
class TypeBuilder<R(A1, A2, A3, A4), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(4);
|
||||
params.push_back(TypeBuilder<A1, 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>
|
||||
class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(5);
|
||||
params.push_back(TypeBuilder<A1, cross>::get(Context));
|
||||
params.push_back(TypeBuilder<A2, cross>::get(Context));
|
||||
@ -321,15 +322,15 @@ class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
|
||||
|
||||
template<typename R, bool cross> class TypeBuilder<R(...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
|
||||
}
|
||||
};
|
||||
template<typename R, typename A1, bool cross>
|
||||
class TypeBuilder<R(A1, ...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(1);
|
||||
params.push_back(TypeBuilder<A1, cross>::get(Context));
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
|
||||
@ -338,8 +339,8 @@ class TypeBuilder<R(A1, ...), cross> {
|
||||
template<typename R, typename A1, typename A2, bool cross>
|
||||
class TypeBuilder<R(A1, A2, ...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(2);
|
||||
params.push_back(TypeBuilder<A1, cross>::get(Context));
|
||||
params.push_back(TypeBuilder<A2, cross>::get(Context));
|
||||
@ -350,8 +351,8 @@ class TypeBuilder<R(A1, A2, ...), cross> {
|
||||
template<typename R, typename A1, typename A2, typename A3, bool cross>
|
||||
class TypeBuilder<R(A1, A2, A3, ...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(3);
|
||||
params.push_back(TypeBuilder<A1, 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>
|
||||
class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(4);
|
||||
params.push_back(TypeBuilder<A1, 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>
|
||||
class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
|
||||
public:
|
||||
static const FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<const Type*> params;
|
||||
static FunctionType *get(LLVMContext &Context) {
|
||||
std::vector<Type*> params;
|
||||
params.reserve(5);
|
||||
params.push_back(TypeBuilder<A1, 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 <cerrno>
|
||||
#include <string>
|
||||
@ -669,7 +669,7 @@ const error_category& generic_category();
|
||||
const error_category& system_category();
|
||||
|
||||
/// 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.
|
||||
const error_category& posix_category();
|
||||
|
||||
|
@ -26,11 +26,19 @@ class SubRegIndex {
|
||||
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
|
||||
// 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 AsmName = n;
|
||||
list<string> AltNames = altNames;
|
||||
|
||||
// Aliases - A list of registers that this register overlaps with. A read or
|
||||
// modification of this register can potentially read or modify the aliased
|
||||
@ -48,6 +56,10 @@ class Register<string n> {
|
||||
// SubRegs.
|
||||
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
|
||||
// a register in SubRegs and are not inherited. The following formats are
|
||||
// supported:
|
||||
@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
|
||||
// registers by register allocators.
|
||||
//
|
||||
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
||||
list<Register> regList> {
|
||||
dag regList, RegAltNameIndex idx = NoRegAltName> {
|
||||
string Namespace = namespace;
|
||||
|
||||
// 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 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
|
||||
// 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.
|
||||
bit isAllocatable = 1;
|
||||
|
||||
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
|
||||
// code into a generated register class. The normal usage of this is to
|
||||
// overload virtual methods.
|
||||
code MethodProtos = [{}];
|
||||
code MethodBodies = [{}];
|
||||
// AltOrders - List of alternative allocation orders. The default order is
|
||||
// MemberList itself, and that is good enough for most targets since the
|
||||
// register allocators automatically remove reserved registers and move
|
||||
// callee-saved registers to the end.
|
||||
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.
|
||||
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;
|
||||
|
||||
// Added complexity passed onto matching pattern.
|
||||
@ -227,6 +329,9 @@ class Instruction {
|
||||
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
|
||||
bit hasExtraSrcRegAllocReq = 0; // Sources 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:
|
||||
//
|
||||
@ -241,6 +346,11 @@ class Instruction {
|
||||
// Is this instruction a "real" instruction (with a distinct machine
|
||||
// encoding), or is it a pseudo instruction used for codegen modeling
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
/// selector matching code. Currently each predicate is just a string.
|
||||
class Predicate<string cond> {
|
||||
@ -277,6 +395,15 @@ class Predicate<string cond> {
|
||||
/// matcher, this is true. Targets should set this by inheriting their
|
||||
/// feature from the AssemblerPredicate class in addition to Predicate.
|
||||
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
|
||||
@ -373,6 +500,7 @@ class Operand<ValueType ty> {
|
||||
string EncoderMethod = "";
|
||||
string DecoderMethod = "";
|
||||
string AsmOperandLowerMethod = ?;
|
||||
string OperandType = "OPERAND_UNKNOWN";
|
||||
dag MIOperandInfo = (ops);
|
||||
|
||||
// ParserMatchClass - The "match class" that operands of this type fit
|
||||
@ -386,6 +514,25 @@ class Operand<ValueType ty> {
|
||||
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 i8imm : Operand<i8>;
|
||||
def i16imm : Operand<i16>;
|
||||
@ -394,6 +541,7 @@ def i64imm : Operand<i64>;
|
||||
|
||||
def f32imm : Operand<f32>;
|
||||
def f64imm : Operand<f64>;
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// matches instructions and aliases.
|
||||
class AssemblerPredicate {
|
||||
class AssemblerPredicate<string cond> {
|
||||
bit AssemblerMatcherPredicate = 1;
|
||||
string AssemblerCondString = cond;
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> class ArrayRef;
|
||||
class MCSection;
|
||||
class MCContext;
|
||||
class MachineFunction;
|
||||
@ -27,30 +28,14 @@ namespace llvm {
|
||||
class TargetLoweringObjectFile;
|
||||
|
||||
class TargetAsmInfo {
|
||||
unsigned PointerSize;
|
||||
bool IsLittleEndian;
|
||||
TargetFrameLowering::StackDirection StackDir;
|
||||
const TargetRegisterInfo *TRI;
|
||||
std::vector<MachineMove> InitialFrameState;
|
||||
const TargetRegisterInfo *TRI;
|
||||
const TargetFrameLowering *TFI;
|
||||
const TargetLoweringObjectFile *TLOF;
|
||||
|
||||
public:
|
||||
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 {
|
||||
return TLOF->getDwarfLineSection();
|
||||
}
|
||||
@ -59,6 +44,10 @@ class TargetAsmInfo {
|
||||
return TLOF->getEHFrameSection();
|
||||
}
|
||||
|
||||
const MCSection *getCompactUnwindSection() const {
|
||||
return TLOF->getCompactUnwindSection();
|
||||
}
|
||||
|
||||
const MCSection *getDwarfFrameSection() const {
|
||||
return TLOF->getDwarfFrameSection();
|
||||
}
|
||||
@ -79,6 +68,12 @@ class TargetAsmInfo {
|
||||
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 {
|
||||
return TRI->getCalleeSavedRegs(MF);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
namespace llvm {
|
||||
class MCStreamer;
|
||||
class StringRef;
|
||||
class Target;
|
||||
class SMLoc;
|
||||
class AsmToken;
|
||||
class MCParsedAsmOperand;
|
||||
@ -26,23 +25,19 @@ class TargetAsmParser : public MCAsmParserExtension {
|
||||
TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT
|
||||
void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT
|
||||
protected: // Can only create subclasses.
|
||||
TargetAsmParser(const Target &);
|
||||
TargetAsmParser();
|
||||
|
||||
/// The Target that this machine was created for.
|
||||
const Target &TheTarget;
|
||||
|
||||
/// The current set of available features.
|
||||
/// AvailableFeatures - The current set of available features.
|
||||
unsigned AvailableFeatures;
|
||||
|
||||
public:
|
||||
virtual ~TargetAsmParser();
|
||||
|
||||
const Target &getTarget() const { return TheTarget; }
|
||||
|
||||
unsigned getAvailableFeatures() const { return AvailableFeatures; }
|
||||
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.
|
||||
///
|
||||
|
@ -259,7 +259,7 @@ class TargetData : public ImmutablePass {
|
||||
/// getIntPtrType - Return an unsigned integer type that is the same size or
|
||||
/// 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
|
||||
/// the specified indices. This is used to implement getelementptr.
|
||||
@ -272,12 +272,6 @@ class TargetData : public ImmutablePass {
|
||||
/// information is lazily cached.
|
||||
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
|
||||
/// global. This includes an explicitly requested alignment (if the global
|
||||
/// has one).
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user