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

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

View File

@ -68,13 +68,6 @@ typedef struct LLVMOpaqueModule *LLVMModuleRef;
*/
typedef struct LLVMOpaqueType *LLVMTypeRef;
/**
* 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 )

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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> > {

View File

@ -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

View File

@ -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);
}
};

View File

@ -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();

View File

@ -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) {

View File

@ -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
/// @{

View File

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

View File

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

View File

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

View File

@ -15,8 +15,9 @@
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#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);

View File

@ -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);

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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);
};
}

View File

@ -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;

View File

@ -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,

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -345,7 +345,7 @@ 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);

View File

@ -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.

View File

@ -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) {

View File

@ -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;

View File

@ -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
//===--------------------------------------------------------------------===//

View File

@ -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.

View File

@ -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 */

View File

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

View File

@ -22,7 +22,7 @@ namespace RTLIB {
/// RTLIB::Libcall enum - This enum defines all of the runtime library calls
/// 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,

View File

@ -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,

View File

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

View File

@ -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);
}

View File

@ -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.
///

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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; }

View File

@ -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.

View File

@ -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());
}

View File

@ -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&);

View File

@ -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) {

View File

@ -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)

View File

@ -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);

View File

@ -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]>;

View File

@ -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.

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
};

View File

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

View File

@ -1,4 +1,4 @@
//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===//
//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -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>

View File

@ -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.

View File

@ -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();

View File

@ -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

View File

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

View File

@ -460,7 +460,8 @@ namespace llvm {
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
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,

View File

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

View File

@ -1,4 +1,4 @@
//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -14,15 +14,14 @@
#ifndef LLVM_OBJECT_OBJECT_FILE_H
#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

View File

@ -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;

View File

@ -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();
}
};

View File

@ -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);
}
};

View File

@ -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 <>

View File

@ -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.

View File

@ -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"

View File

@ -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);

View File

@ -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);
}
};

View File

@ -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.

View File

@ -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));
}
};

View File

@ -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));

View File

@ -222,7 +222,7 @@ template <> struct hash<std::error_code>;
*/
#include "llvm/Config/config.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/type_traits.h"
#include <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();

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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.
///

View File

@ -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