Upgrade our copy of llvm/clang to r168974, from upstream's release_32

branch.  This is effectively llvm/clang 3.2 RC2; the 3.2 release is
coming soon.
This commit is contained in:
Dimitry Andric 2012-12-03 19:24:08 +00:00
commit 3861d79fd7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=243830
1658 changed files with 106226 additions and 43409 deletions

View File

@ -173,10 +173,11 @@ typedef enum {
LLVMUWTable = 1 << 30,
LLVMNonLazyBind = 1 << 31
// FIXME: This attribute is currently not included in the C API as
// a temporary measure until the API/ABI impact to the C API is understood
// and the path forward agreed upon.
//LLVMAddressSafety = 1ULL << 32
/* FIXME: This attribute is currently not included in the C API as
a temporary measure until the API/ABI impact to the C API is understood
and the path forward agreed upon.
LLVMAddressSafety = 1ULL << 32
*/
} LLVMAttribute;
typedef enum {
@ -282,6 +283,7 @@ typedef enum {
LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/
LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something
equivalent. */
LLVMLinkOnceODRAutoHideLinkage, /**< Like LinkOnceODR, but possibly hidden. */
LLVMWeakAnyLinkage, /**< Keep one copy of function when linking (weak) */
LLVMWeakODRLinkage, /**< Same, but only replaced by something
equivalent. */
@ -295,9 +297,7 @@ typedef enum {
LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */
LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */
LLVMLinkerPrivateWeakLinkage, /**< Like LinkerPrivate, but is weak. */
LLVMLinkerPrivateWeakDefAutoLinkage /**< Like LinkerPrivateWeak, but possibly
hidden. */
LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */
} LLVMLinkage;
typedef enum {
@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
* Set the alignment for a function parameter.
*
* @see llvm::Argument::addAttr()
* @see llvm::Attribute::constructAlignmentFromInt()
* @see llvm::AttrBuilder::addAlignmentAttr()
*/
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
@ -1868,6 +1868,27 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
*/
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
/**
* Obtain the number of operands from an MDNode value.
*
* @param V MDNode to get number of operands from.
* @return Number of operands of the MDNode.
*/
unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V);
/**
* Obtain the given MDNode's operands.
*
* The passed LLVMValueRef pointer should point to enough memory to hold all of
* the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as
* LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the
* MDNode's operands.
*
* @param V MDNode to get the operands from.
* @param Dest Destination array for operands.
*/
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest);
/**
* @}
*/
@ -2688,7 +2709,7 @@ namespace llvm {
template<typename T>
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
#if DEBUG
#ifdef DEBUG
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
cast<T>(*I);
#endif

View File

@ -145,6 +145,15 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Set the disassembler's options. Returns 1 if it can set the Options and 0
* otherwise.
*/
int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
/* The option to produce marked up assembly. */
#define LLVMDisassembler_Option_UseMarkup 1
/**
* Dispose of a disassembler context.
*/

View File

@ -145,7 +145,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
/*===-- Target Data -------------------------------------------------------===*/
/** Creates target data from a target layout string.
See the constructor llvm::TargetData::TargetData. */
See the constructor llvm::DataLayout::DataLayout. */
LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
/** Adds target data information to a pass manager. This does not take ownership
@ -160,48 +160,58 @@ void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
See the constructor llvm::TargetData::TargetData. */
See the constructor llvm::DataLayout::DataLayout. */
char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
/** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
See the method llvm::TargetData::isLittleEndian. */
See the method llvm::DataLayout::isLittleEndian. */
enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target.
See the method llvm::TargetData::getPointerSize. */
See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSize(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target for a specified
address space.
See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSizeForAS(LLVMTargetDataRef, unsigned AS);
/** Returns the integer type that is the same size as a pointer on a target.
See the method llvm::TargetData::getIntPtrType. */
See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
/** Returns the integer type that is the same size as a pointer on a target.
This version allows the address space to be specified.
See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef, unsigned AS);
/** Computes the size of a type in bytes for a target.
See the method llvm::TargetData::getTypeSizeInBits. */
See the method llvm::DataLayout::getTypeSizeInBits. */
unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the storage size of a type in bytes for a target.
See the method llvm::TargetData::getTypeStoreSize. */
See the method llvm::DataLayout::getTypeStoreSize. */
unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI size of a type in bytes for a target.
See the method llvm::TargetData::getTypeAllocSize. */
See the method llvm::DataLayout::getTypeAllocSize. */
unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the call frame alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a global variable in bytes for a target.
See the method llvm::TargetData::getPreferredAlignment. */
See the method llvm::DataLayout::getPreferredAlignment. */
unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
LLVMValueRef GlobalVar);
@ -216,7 +226,7 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned Element);
/** Deallocates a TargetData.
See the destructor llvm::TargetData::~TargetData. */
See the destructor llvm::DataLayout::~DataLayout. */
void LLVMDisposeTargetData(LLVMTargetDataRef);
/**
@ -227,15 +237,15 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
}
namespace llvm {
class TargetData;
class DataLayout;
class TargetLibraryInfo;
inline TargetData *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<TargetData*>(P);
inline DataLayout *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<DataLayout*>(P);
}
inline LLVMTargetDataRef wrap(const TargetData *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
inline LLVMTargetDataRef wrap(const DataLayout *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {

View File

@ -104,7 +104,7 @@ char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
LLVMDisposeMessage. */
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
/** Emits an asm or object file for the given module to the filename. This

View File

@ -36,6 +36,9 @@ extern "C" {
/** See llvm::createBBVectorizePass function. */
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
/** See llvm::createLoopVectorizePass function. */
void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
/**
* @}
*/

View File

@ -455,14 +455,11 @@ namespace llvm {
/* The sign bit of this number. */
unsigned int sign: 1;
/* For PPCDoubleDouble, we have a second exponent and sign (the second
significand is appended to the first one, although it would be wrong to
regard these as a single number for arithmetic purposes). These fields
are not meaningful for any other type. */
exponent_t exponent2 : 11;
unsigned int sign2: 1;
};
// See friend declaration above. This additional declaration is required in
// order to compile LLVM with IBM xlC compiler.
hash_code hash_value(const APFloat &Arg);
} /* namespace llvm */
#endif /* LLVM_FLOAT_H */

View File

@ -251,7 +251,7 @@ class APInt {
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
/// This constructor interprets the string \arg str in the given radix. The
/// This constructor interprets the string \p str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
/// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
@ -760,7 +760,7 @@ class APInt {
APInt shl(unsigned shiftAmt) const {
assert(shiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (shiftAmt == BitWidth)
if (shiftAmt >= BitWidth)
return APInt(BitWidth, 0); // avoid undefined shift results
return APInt(BitWidth, VAL << shiftAmt);
}
@ -1231,15 +1231,15 @@ class APInt {
}
/// This method determines how many bits are required to hold the APInt
/// equivalent of the string given by \arg str.
/// equivalent of the string given by \p str.
/// @brief Get bits required for string value.
static unsigned getBitsNeeded(StringRef str, uint8_t radix);
/// countLeadingZeros - This function is an APInt version of the
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
/// of zeros from the most significant bit to the first one bit.
/// @returns BitWidth if the value is zero.
/// @returns the number of zeros from the most significant bit to the first
/// @returns BitWidth if the value is zero, otherwise
/// returns the number of zeros from the most significant bit to the first
/// one bits.
unsigned countLeadingZeros() const {
if (isSingleWord()) {
@ -1252,8 +1252,8 @@ class APInt {
/// countLeadingOnes - This function is an APInt version of the
/// countLeadingOnes_{32,64} functions in MathExtras.h. It counts the number
/// of ones from the most significant bit to the first zero bit.
/// @returns 0 if the high order bit is not set
/// @returns the number of 1 bits from the most significant to the least
/// @returns 0 if the high order bit is not set, otherwise
/// returns the number of 1 bits from the most significant to the least
/// @brief Count the number of leading one bits.
unsigned countLeadingOnes() const;
@ -1266,8 +1266,8 @@ class APInt {
/// countTrailingZeros - This function is an APInt version of the
/// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first set bit.
/// @returns BitWidth if the value is zero.
/// @returns the number of zeros from the least significant bit to the first
/// @returns BitWidth if the value is zero, otherwise
/// returns the number of zeros from the least significant bit to the first
/// one bit.
/// @brief Count the number of trailing zero bits.
unsigned countTrailingZeros() const;
@ -1275,8 +1275,8 @@ class APInt {
/// countTrailingOnes - This function is an APInt version of the
/// countTrailingOnes_{32,64} functions in MathExtras.h. It counts
/// the number of ones from the least significant bit to the first zero bit.
/// @returns BitWidth if the value is all ones.
/// @returns the number of ones from the least significant bit to the first
/// @returns BitWidth if the value is all ones, otherwise
/// returns the number of ones from the least significant bit to the first
/// zero bit.
/// @brief Count the number of trailing one bits.
unsigned countTrailingOnes() const {
@ -1288,8 +1288,8 @@ class APInt {
/// countPopulation - This function is an APInt version of the
/// countPopulation_{32,64} functions in MathExtras.h. It counts the number
/// of 1 bits in the APInt value.
/// @returns 0 if the value is zero.
/// @returns the number of set bits.
/// @returns 0 if the value is zero, otherwise returns the number of set
/// bits.
/// @brief Count the number of bits set.
unsigned countPopulation() const {
if (isSingleWord())
@ -1780,6 +1780,9 @@ inline APInt Not(const APInt& APIVal) {
} // End of APIntOps namespace
// See friend declaration above. This additional declaration is required in
// order to compile LLVM with IBM xlC compiler.
hash_code hash_value(const APInt &Arg);
} // End of llvm namespace
#endif

View File

@ -59,12 +59,17 @@ namespace llvm {
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector.
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a SmallVector. This is templated in order to
/// avoid instantiating SmallVectorTemplateCommon<T> whenever we
/// copy-construct an ArrayRef.
template<typename U>
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
: Data(Vec.data()), Length(Vec.size()) {
}
/// Construct an ArrayRef from a std::vector.
/*implicit*/ ArrayRef(const std::vector<T> &Vec)
template<typename A>
/*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
: Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
/// Construct an ArrayRef from a C array.

View File

@ -172,7 +172,7 @@ class BitVector {
unsigned BitPos = Prev % BITWORD_SIZE;
BitWord Copy = Bits[WordPos];
// Mask off previous bits.
Copy &= ~0L << BitPos;
Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
@ -237,6 +237,34 @@ class BitVector {
return *this;
}
/// set - Efficiently set a range of bits in [I, E)
BitVector &set(unsigned I, unsigned E) {
assert(I <= E && "Attempted to set backwards range!");
assert(E <= size() && "Attempted to set out-of-bounds range!");
if (I == E) return *this;
if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
BitWord EMask = 1UL << (E % BITWORD_SIZE);
BitWord IMask = 1UL << (I % BITWORD_SIZE);
BitWord Mask = EMask - IMask;
Bits[I / BITWORD_SIZE] |= Mask;
return *this;
}
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
Bits[I / BITWORD_SIZE] |= PrefixMask;
I = RoundUpToAlignment(I, BITWORD_SIZE);
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
Bits[I / BITWORD_SIZE] = ~0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] |= PostfixMask;
return *this;
}
BitVector &reset() {
init_words(Bits, Capacity, false);
return *this;
@ -247,6 +275,34 @@ class BitVector {
return *this;
}
/// reset - Efficiently reset a range of bits in [I, E)
BitVector &reset(unsigned I, unsigned E) {
assert(I <= E && "Attempted to reset backwards range!");
assert(E <= size() && "Attempted to reset out-of-bounds range!");
if (I == E) return *this;
if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
BitWord EMask = 1UL << (E % BITWORD_SIZE);
BitWord IMask = 1UL << (I % BITWORD_SIZE);
BitWord Mask = EMask - IMask;
Bits[I / BITWORD_SIZE] &= ~Mask;
return *this;
}
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
Bits[I / BITWORD_SIZE] &= ~PrefixMask;
I = RoundUpToAlignment(I, BITWORD_SIZE);
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
Bits[I / BITWORD_SIZE] = 0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] &= ~PostfixMask;
return *this;
}
BitVector &flip() {
for (unsigned i = 0; i < NumBitWords(size()); ++i)
Bits[i] = ~Bits[i];
@ -311,7 +367,7 @@ class BitVector {
return !(*this == RHS);
}
// Intersection, union, disjoint union.
/// Intersection, union, disjoint union.
BitVector &operator&=(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
@ -328,7 +384,7 @@ class BitVector {
return *this;
}
// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
/// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
BitVector &reset(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
@ -338,6 +394,23 @@ class BitVector {
return *this;
}
/// test - Check if (This - RHS) is zero.
/// This is the same as reset(RHS) and any().
bool test(const BitVector &RHS) const {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
unsigned i;
for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
if ((Bits[i] & ~RHS.Bits[i]) != 0)
return true;
for (; i != ThisWords ; ++i)
if (Bits[i] != 0)
return true;
return false;
}
BitVector &operator|=(const BitVector &RHS) {
if (size() < RHS.size())
resize(RHS.size());
@ -451,8 +524,11 @@ class BitVector {
// Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE;
if (ExtraBits) {
Bits[UsedWords-1] &= ~(~0L << ExtraBits);
Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
BitWord ExtraBitMask = ~0UL << ExtraBits;
if (t)
Bits[UsedWords-1] |= ExtraBitMask;
else
Bits[UsedWords-1] &= ~ExtraBitMask;
}
}

View File

@ -48,17 +48,18 @@ class DAGDeltaAlgorithm {
public:
virtual ~DAGDeltaAlgorithm() {}
/// Run - Minimize the DAG formed by the \arg Changes vertices and the \arg
/// Dependencies edges by executing \see ExecuteOneTest() on subsets of
/// Run - Minimize the DAG formed by the \p Changes vertices and the
/// \p Dependencies edges by executing \see ExecuteOneTest() on subsets of
/// changes and returning the smallest set which still satisfies the test
/// predicate and the input \arg Dependencies.
/// predicate and the input \p Dependencies.
///
/// \param Changes The list of changes.
///
/// \param Dependencies The list of dependencies amongst changes. For each
/// (x,y) in \arg Dependencies, both x and y must be in \arg Changes. The
/// minimization algorithm guarantees that for each tested changed set S, x
/// \in S implies y \in S. It is an error to have cyclic dependencies.
/// (x,y) in \p Dependencies, both x and y must be in \p Changes. The
/// minimization algorithm guarantees that for each tested changed set S,
/// \f$ x \in S \f$ implies \f$ y \in S \f$. It is an error to have cyclic
/// dependencies.
changeset_ty Run(const changeset_ty &Changes,
const std::vector<edge_ty> &Dependencies);
@ -67,7 +68,7 @@ class DAGDeltaAlgorithm {
const changesetlist_ty &Sets,
const changeset_ty &Required) {}
/// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
/// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
};

View File

@ -45,23 +45,23 @@ class DeltaAlgorithm {
/// since we always reduce following a success.
std::set<changeset_ty> FailedTestsCache;
/// GetTestResult - Get the test result for the \arg Changes from the
/// GetTestResult - Get the test result for the \p Changes from the
/// cache, executing the test if necessary.
///
/// \param Changes - The change set to test.
/// \return - The test result.
bool GetTestResult(const changeset_ty &Changes);
/// Split - Partition a set of changes \arg S into one or two subsets.
/// Split - Partition a set of changes \p S into one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
/// Delta - Minimize a set of \arg Changes which has been partioned into
/// Delta - Minimize a set of \p Changes which has been partioned into
/// smaller sets, by attempting to remove individual subsets.
changeset_ty Delta(const changeset_ty &Changes,
const changesetlist_ty &Sets);
/// Search - Search for a subset (or subsets) in \arg Sets which can be
/// removed from \arg Changes while still satisfying the predicate.
/// Search - Search for a subset (or subsets) in \p Sets which can be
/// removed from \p Changes while still satisfying the predicate.
///
/// \param Res - On success, a subset of Changes which satisfies the
/// predicate.
@ -74,13 +74,13 @@ class DeltaAlgorithm {
virtual void UpdatedSearchState(const changeset_ty &Changes,
const changesetlist_ty &Sets) {}
/// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
/// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
public:
virtual ~DeltaAlgorithm();
/// Run - Minimize the set \arg Changes by executing \see ExecuteOneTest() on
/// Run - Minimize the set \p Changes by executing \see ExecuteOneTest() on
/// subsets of changes and returning the smallest set which still satisfies
/// the test predicate.
changeset_ty Run(const changeset_ty &Changes);

View File

@ -420,9 +420,10 @@ class DenseMapBase {
NumBuckets = getNumBuckets();
}
if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
this->grow(NumBuckets);
this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket);
}
assert(TheBucket);
// Only update the state after we've grown our bucket space appropriately
// so that when growing buckets we have self-consistent entry count.
@ -599,7 +600,7 @@ class DenseMap
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast)));
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast-1)));
assert(Buckets);
if (!OldBuckets) {
this->BaseT::initEmpty();
@ -825,11 +826,11 @@ class SmallDenseMap
}
void grow(unsigned AtLeast) {
if (AtLeast > InlineBuckets)
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast));
if (AtLeast >= InlineBuckets)
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
if (Small) {
if (AtLeast <= InlineBuckets)
if (AtLeast < InlineBuckets)
return; // Nothing to do.
// First move the inline buckets into a temporary storage.

View File

@ -31,12 +31,12 @@ struct DenseMapInfo {
template<typename T>
struct DenseMapInfo<T*> {
static inline T* getEmptyKey() {
intptr_t Val = -1;
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
static inline T* getTombstoneKey() {
intptr_t Val = -2;
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
@ -105,7 +105,7 @@ template<> struct DenseMapInfo<int> {
// Provide DenseMapInfo for longs.
template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() {
return (1UL << (sizeof(long) * 8 - 1)) - 1L;
return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {

View File

@ -33,6 +33,7 @@ namespace llvm {
///
/// Here is a simple example using integers:
///
/// \code
/// EquivalenceClasses<int> EC;
/// EC.unionSets(1, 2); // insert 1, 2 into the same set
/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
@ -46,6 +47,7 @@ namespace llvm {
/// cerr << *MI << " "; // Print member.
/// cerr << "\n"; // Finish set.
/// }
/// \endcode
///
/// This example prints:
/// 4

View File

@ -278,6 +278,10 @@ class FoldingSetNodeIDRef {
bool operator==(FoldingSetNodeIDRef) const;
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(FoldingSetNodeIDRef) const;
const unsigned *getData() const { return Data; }
size_t getSize() const { return Size; }
};
@ -327,6 +331,11 @@ class FoldingSetNodeID {
bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(const FoldingSetNodeID &RHS) const;
bool operator<(const FoldingSetNodeIDRef RHS) const;
/// Intern - Copy this node's data to a memory region allocated from the
/// given allocator and return a FoldingSetNodeIDRef describing the
/// interned data.

View File

@ -409,7 +409,6 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
/// combining them, this (as an optimization) directly combines the integers.
template <typename InputIteratorT>
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
typedef typename std::iterator_traits<InputIteratorT>::value_type ValueT;
const size_t seed = get_execution_seed();
char buffer[64], *buffer_ptr = buffer;
char *const buffer_end = buffer_ptr + array_lengthof(buffer);
@ -711,7 +710,7 @@ hash_code hash_combine(const T1 &arg1) {
#endif
// Implementation details for implementatinos of hash_value overloads provided
// Implementation details for implementations of hash_value overloads provided
// here.
namespace hashing {
namespace detail {

View File

@ -33,9 +33,8 @@ class ImmutableListImpl : public FoldingSetNode {
friend class ImmutableListFactory<T>;
// Do not implement.
void operator=(const ImmutableListImpl&);
ImmutableListImpl(const ImmutableListImpl&);
void operator=(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
ImmutableListImpl(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
public:
const T& getHead() const { return Head; }

View File

@ -122,8 +122,8 @@ class ImmutableMap {
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
bool contains(key_type_ref K) const {

View File

@ -22,7 +22,6 @@
#include <cassert>
#include <functional>
#include <vector>
#include <stdio.h>
namespace llvm {
@ -84,13 +83,13 @@ class ImutAVLTree {
}
return NULL;
}
/// getMaxElement - Find the subtree associated with the highest ranged
/// key value.
ImutAVLTree* getMaxElement() {
ImutAVLTree *T = this;
ImutAVLTree *Right = T->getRight();
while (Right) { T = right; right = T->getRight(); }
ImutAVLTree *Right = T->getRight();
while (Right) { T = Right; Right = T->getRight(); }
return T;
}
@ -258,7 +257,7 @@ class ImutAVLTree {
/// method returns false for an instance of ImutAVLTree, all subtrees
/// will also have this method return false. The converse is not true.
bool isMutable() const { return IsMutable; }
/// hasCachedDigest - Returns true if the digest for this tree is cached.
/// This can only be true if the tree is immutable.
bool hasCachedDigest() const { return IsDigestCached; }
@ -280,7 +279,7 @@ class ImutAVLTree {
assert(isMutable() && "Mutable flag already removed.");
IsMutable = false;
}
/// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
void markedCachedDigest() {
assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
@ -349,7 +348,7 @@ class ImutAVLTree {
else
factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
}
// We need to clear the mutability bit in case we are
// destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
IsMutable = false;
@ -415,7 +414,7 @@ class ImutAVLFactory {
TreeTy* getEmptyTree() const { return NULL; }
protected:
//===--------------------------------------------------===//
// A bunch of quick helper functions used for reasoning
// about the properties of trees and their children.
@ -461,7 +460,7 @@ class ImutAVLFactory {
// returned to the caller.
//===--------------------------------------------------===//
TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
BumpPtrAllocator& A = getAllocator();
TreeTy* T;
if (!freeNodes.empty()) {
@ -469,8 +468,7 @@ class ImutAVLFactory {
freeNodes.pop_back();
assert(T != L);
assert(T != R);
}
else {
} else {
T = (TreeTy*) A.Allocate<TreeTy>();
}
new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
@ -513,7 +511,8 @@ class ImutAVLFactory {
return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
}
else if (hr > hl + 2) {
if (hr > hl + 2) {
assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
TreeTy *RL = getLeft(R);
@ -529,8 +528,8 @@ class ImutAVLFactory {
return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
}
else
return createNode(L,V,R);
return createNode(L,V,R);
}
/// add_internal - Creates a new tree that includes the specified
@ -604,7 +603,7 @@ class ImutAVLFactory {
markImmutable(getLeft(T));
markImmutable(getRight(T));
}
public:
TreeTy *getCanonicalTree(TreeTy *TNew) {
if (!TNew)
@ -937,7 +936,7 @@ class ImmutableSet {
private:
TreeTy *Root;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@ -1006,10 +1005,10 @@ class ImmutableSet {
typename TreeTy::Factory *getTreeFactory() const {
return const_cast<typename TreeTy::Factory *>(&F);
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
friend class Factory;
@ -1027,11 +1026,11 @@ class ImmutableSet {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
TreeTy *getRoot() {
TreeTy *getRoot() {
if (Root) { Root->retain(); }
return Root;
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
@ -1092,7 +1091,7 @@ class ImmutableSet {
void validateTree() const { if (Root) Root->validateTree(); }
};
// NOTE: This may some day replace the current ImmutableSet.
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
class ImmutableSetRef {
@ -1101,11 +1100,11 @@ class ImmutableSetRef {
typedef typename ValInfo::value_type_ref value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
private:
TreeTy *Root;
FactoryTy *Factory;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@ -1133,44 +1132,44 @@ class ImmutableSetRef {
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
ImmutableSetRef add(value_type_ref V) {
return ImmutableSetRef(Factory->add(Root, V), Factory);
}
ImmutableSetRef remove(value_type_ref V) {
return ImmutableSetRef(Factory->remove(Root, V), Factory);
}
/// Returns true if the set contains the specified value.
bool contains(value_type_ref V) const {
return Root ? Root->contains(V) : false;
}
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
return ImmutableSet<ValT>(canonicalize ?
Factory->getCanonicalTree(Root) : Root);
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
bool operator==(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
bool operator!=(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
/// isSingleton - Return true if the set contains exactly one element.
/// This method runs in constant time.
bool isSingleton() const { return getHeight() == 1; }
@ -1178,7 +1177,7 @@ class ImmutableSetRef {
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
class iterator {
typename TreeTy::iterator itr;
iterator(TreeTy* t) : itr(t) {}
@ -1194,28 +1193,28 @@ class ImmutableSetRef {
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
inline value_type *operator->() const { return &(operator*()); }
};
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
ID.AddPointer(S.Root);
}
inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID,*this);
}
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
void validateTree() const { if (Root) Root->validateTree(); }
};

View File

@ -0,0 +1,90 @@
//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a map that provides insertion order iteration. The
// interface is purposefully minimal. The key is assumed to be cheap to copy
// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
// a std::vector.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_MAPVECTOR_H
#define LLVM_ADT_MAPVECTOR_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include <vector>
namespace llvm {
/// This class implements a map that also provides access to all stored values
/// in a deterministic order. The values are kept in a std::vector and the
/// mapping is done with DenseMap from Keys to indexes in that vector.
template<typename KeyT, typename ValueT,
typename MapType = llvm::DenseMap<KeyT, unsigned>,
typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
class MapVector {
typedef typename VectorType::size_type SizeType;
MapType Map;
VectorType Vector;
public:
typedef typename VectorType::iterator iterator;
typedef typename VectorType::const_iterator const_iterator;
SizeType size() const {
return Vector.size();
}
iterator begin() {
return Vector.begin();
}
const_iterator begin() const {
return Vector.begin();
}
iterator end() {
return Vector.end();
}
const_iterator end() const {
return Vector.end();
}
bool empty() const {
return Vector.empty();
}
void clear() {
Map.clear();
Vector.clear();
}
ValueT &operator[](const KeyT &Key) {
std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
unsigned &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(Key, ValueT()));
I = Vector.size() - 1;
}
return Vector[I].second;
}
unsigned count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
}
};
}
#endif

View File

@ -16,8 +16,13 @@
#ifndef LLVM_ADT_OPTIONAL
#define LLVM_ADT_OPTIONAL
#include "llvm/Support/Compiler.h"
#include <cassert>
#if LLVM_USE_RVALUE_REFERENCES
#include <utility>
#endif
namespace llvm {
template<typename T>
@ -28,6 +33,10 @@ class Optional {
explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
#if LLVM_USE_RVALUE_REFERENCES
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}

View File

@ -14,6 +14,7 @@
#ifndef LLVM_ADT_OWNING_PTR_H
#define LLVM_ADT_OWNING_PTR_H
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
@ -25,12 +26,21 @@ namespace llvm {
/// pointee object can be taken away from OwningPtr by using the take method.
template<class T>
class OwningPtr {
OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT
OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT
OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
OwningPtr &operator=(OwningPtr &&Other) {
reset(Other.take());
return *this;
}
#endif
~OwningPtr() {
delete Ptr;
}
@ -79,12 +89,21 @@ inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
/// functionality as OwningPtr, except that it works for array types.
template<class T>
class OwningArrayPtr {
OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT
OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
reset(Other.take());
return *this;
}
#endif
~OwningArrayPtr() {
delete [] Ptr;
}

View File

@ -19,32 +19,32 @@
namespace llvm {
template <typename T, unsigned BitNum, bool isSigned>
template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
class PackedVectorBase;
// This won't be necessary if we can specialize members without specializing
// the parent template.
template <typename T, unsigned BitNum>
class PackedVectorBase<T, BitNum, false> {
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, false> {
protected:
static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
return val;
}
static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
assert((val >> BitNum) == 0 && "value is too big");
for (unsigned i = 0; i != BitNum; ++i)
Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
}
};
template <typename T, unsigned BitNum>
class PackedVectorBase<T, BitNum, true> {
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, true> {
protected:
static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum-1; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
@ -53,7 +53,7 @@ class PackedVectorBase<T, BitNum, true> {
return val;
}
static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
if (val < 0) {
val = ~val;
Bits.set((Idx << (BitNum-1)) + BitNum-1);
@ -71,11 +71,12 @@ class PackedVectorBase<T, BitNum, true> {
/// @endcode
/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
/// an assertion.
template <typename T, unsigned BitNum>
class PackedVector : public PackedVectorBase<T, BitNum,
template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> {
llvm::BitVector Bits;
typedef PackedVectorBase<T, BitNum, std::numeric_limits<T>::is_signed> base;
BitVectorTy Bits;
typedef PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> base;
public:
class reference {

View File

@ -135,12 +135,12 @@ template<typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
intptr_t Val = -1;
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
}
static Ty getTombstoneKey() {
intptr_t Val = -2;
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
}

View File

@ -90,8 +90,8 @@ class ScopedHashTableScope {
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
ScopedHashTableVal<K, V> *LastValInScope;
void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
void operator=(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
ScopedHashTableScope(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
public:
ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope();

View File

@ -27,10 +27,11 @@
namespace llvm {
/// \brief A vector that has set insertion semantics.
///
/// This adapter class provides a way to keep a set of things that also has the
/// property of a deterministic iteration order. The order of iteration is the
/// order of insertion.
/// @brief A vector that has set insertion semantics.
template <typename T, typename Vector = std::vector<T>,
typename Set = SmallSet<T, 16> >
class SetVector {
@ -45,59 +46,59 @@ class SetVector {
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::size_type size_type;
/// @brief Construct an empty SetVector
/// \brief Construct an empty SetVector
SetVector() {}
/// @brief Initialize a SetVector with a range of elements
/// \brief Initialize a SetVector with a range of elements
template<typename It>
SetVector(It Start, It End) {
insert(Start, End);
}
/// @brief Determine if the SetVector is empty or not.
/// \brief Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
}
/// @brief Determine the number of elements in the SetVector.
/// \brief Determine the number of elements in the SetVector.
size_type size() const {
return vector_.size();
}
/// @brief Get an iterator to the beginning of the SetVector.
/// \brief Get an iterator to the beginning of the SetVector.
iterator begin() {
return vector_.begin();
}
/// @brief Get a const_iterator to the beginning of the SetVector.
/// \brief Get a const_iterator to the beginning of the SetVector.
const_iterator begin() const {
return vector_.begin();
}
/// @brief Get an iterator to the end of the SetVector.
/// \brief Get an iterator to the end of the SetVector.
iterator end() {
return vector_.end();
}
/// @brief Get a const_iterator to the end of the SetVector.
/// \brief Get a const_iterator to the end of the SetVector.
const_iterator end() const {
return vector_.end();
}
/// @brief Return the last element of the SetVector.
/// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
return vector_.back();
}
/// @brief Index into the SetVector.
/// \brief Index into the SetVector.
const_reference operator[](size_type n) const {
assert(n < vector_.size() && "SetVector access out of range!");
return vector_[n];
}
/// @returns true iff the element was inserted into the SetVector.
/// @brief Insert a new element into the SetVector.
/// \brief Insert a new element into the SetVector.
/// \returns true iff the element was inserted into the SetVector.
bool insert(const value_type &X) {
bool result = set_.insert(X);
if (result)
@ -105,7 +106,7 @@ class SetVector {
return result;
}
/// @brief Insert a range of elements into the SetVector.
/// \brief Insert a range of elements into the SetVector.
template<typename It>
void insert(It Start, It End) {
for (; Start != End; ++Start)
@ -113,7 +114,7 @@ class SetVector {
vector_.push_back(*Start);
}
/// @brief Remove an item from the set vector.
/// \brief Remove an item from the set vector.
bool remove(const value_type& X) {
if (set_.erase(X)) {
typename vector_type::iterator I =
@ -125,20 +126,44 @@ class SetVector {
return false;
}
/// \brief Remove items from the set vector based on a predicate function.
///
/// This is intended to be equivalent to the following code, if we could
/// write it:
///
/// \code
/// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
/// \endcode
///
/// However, SetVector doesn't expose non-const iterators, making any
/// algorithm like remove_if impossible to use.
///
/// \returns true if any element is removed.
template <typename UnaryPredicate>
bool remove_if(UnaryPredicate P) {
typename vector_type::iterator I
= std::remove_if(vector_.begin(), vector_.end(),
TestAndEraseFromSet<UnaryPredicate>(P, set_));
if (I == vector_.end())
return false;
vector_.erase(I, vector_.end());
return true;
}
/// @returns 0 if the element is not in the SetVector, 1 if it is.
/// @brief Count the number of elements of a given key in the SetVector.
/// \brief Count the number of elements of a given key in the SetVector.
/// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
return set_.count(key);
}
/// @brief Completely clear the SetVector
/// \brief Completely clear the SetVector
void clear() {
set_.clear();
vector_.clear();
}
/// @brief Remove the last element of the SetVector.
/// \brief Remove the last element of the SetVector.
void pop_back() {
assert(!empty() && "Cannot remove an element from an empty SetVector!");
set_.erase(back());
@ -160,18 +185,41 @@ class SetVector {
}
private:
/// \brief A wrapper predicate designed for use with std::remove_if.
///
/// This predicate wraps a predicate suitable for use with std::remove_if to
/// call set_.erase(x) on each element which is slated for removal.
template <typename UnaryPredicate>
class TestAndEraseFromSet {
UnaryPredicate P;
set_type &set_;
public:
typedef typename UnaryPredicate::argument_type argument_type;
TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
bool operator()(argument_type Arg) {
if (P(Arg)) {
set_.erase(Arg);
return true;
}
return false;
}
};
set_type set_; ///< The set.
vector_type vector_; ///< The vector.
};
/// SmallSetVector - A SetVector that performs no allocations if smaller than
/// \brief A SetVector that performs no allocations if smaller than
/// a certain size.
template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
public:
SmallSetVector() {}
/// @brief Initialize a SmallSetVector with a range of elements
/// \brief Initialize a SmallSetVector with a range of elements
template<typename It>
SmallSetVector(It Start, It End) {
this->insert(Start, End);

View File

@ -300,6 +300,21 @@ class SmallBitVector {
return *this;
}
/// set - Efficiently set a range of bits in [I, E)
SmallBitVector &set(unsigned I, unsigned E) {
assert(I <= E && "Attempted to set backwards range!");
assert(E <= size() && "Attempted to set out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
uintptr_t EMask = ((uintptr_t)1) << E;
uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() | Mask);
} else
getPointer()->set(I, E);
return *this;
}
SmallBitVector &reset() {
if (isSmall())
setSmallBits(0);
@ -316,6 +331,21 @@ class SmallBitVector {
return *this;
}
/// reset - Efficiently reset a range of bits in [I, E)
SmallBitVector &reset(unsigned I, unsigned E) {
assert(I <= E && "Attempted to reset backwards range!");
assert(E <= size() && "Attempted to reset out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
uintptr_t EMask = ((uintptr_t)1) << E;
uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() & ~Mask);
} else
getPointer()->reset(I, E);
return *this;
}
SmallBitVector &flip() {
if (isSmall())
setSmallBits(~getSmallBits());

View File

@ -15,12 +15,13 @@
#ifndef LLVM_ADT_SMALLPTRSET_H
#define LLVM_ADT_SMALLPTRSET_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iterator>
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
namespace llvm {
@ -132,7 +133,7 @@ class SmallPtrSetImpl {
/// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(unsigned NewSize);
void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION;
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.

View File

@ -44,25 +44,25 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Assignment
/// @{
/// Assign from a repeated element
/// Assign from a repeated element.
void assign(size_t NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
/// Assign from an iterator pair
/// Assign from an iterator pair.
template<typename in_iter>
void assign(in_iter S, in_iter E) {
this->clear();
SmallVectorImpl<char>::append(S, E);
}
/// Assign from a StringRef
/// Assign from a StringRef.
void assign(StringRef RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Assign from a SmallVector
/// Assign from a SmallVector.
void assign(const SmallVectorImpl<char> &RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
@ -72,7 +72,7 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Concatenation
/// @{
/// Append from an iterator pair
/// Append from an iterator pair.
template<typename in_iter>
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
@ -83,12 +83,12 @@ class SmallString : public SmallVector<char, InternalLen> {
}
/// Append from a StringRef
/// Append from a StringRef.
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Append from a SmallVector
/// Append from a SmallVector.
void append(const SmallVectorImpl<char> &RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
@ -97,19 +97,19 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Comparison
/// @{
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
/// Check for string equality. This is more efficient than compare() when
/// the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
/// equals_lower - Check for string equality, ignoring case.
/// Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \arg RHS.
/// Compare two strings; the result is -1, 0, or 1 if this string is
/// lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
return str().compare(RHS);
}
@ -129,12 +129,12 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \arg Prefix.
/// startswith - Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
/// endswith - Check if this string ends with the given \arg Suffix.
/// endswith - Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
@ -143,76 +143,76 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Searching
/// @{
/// find - Search for the first character \arg C in the string.
/// find - Search for the first character \p C in the string.
///
/// \return - The index of the first occurrence of \arg C, or npos if not
/// \return - The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
return str().find(C, From);
}
/// find - Search for the first string \arg Str in the string.
/// Search for the first string \p Str in the string.
///
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
return str().find(Str, From);
}
/// rfind - Search for the last character \arg C in the string.
/// Search for the last character \p C in the string.
///
/// \return - The index of the last occurrence of \arg C, or npos if not
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
return str().rfind(C, From);
}
/// rfind - Search for the last string \arg Str in the string.
/// Search for the last string \p Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
return str().rfind(Str);
}
/// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find.
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
size_t find_first_of(char C, size_t From = 0) const {
return str().find_first_of(C, From);
}
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// \arg C or npos if not found.
/// Find the first character in the string that is not \p C or npos if not
/// found.
size_t find_first_not_of(char C, size_t From = 0) const {
return str().find_first_not_of(C, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found.
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
/// find_last_of - Find the last character in the string that is \arg C, or
/// npos if not found.
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
return str().find_last_of(C, From);
}
/// find_last_of - Find the last character in the string that is in \arg C,
/// or npos if not found.
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
return str().find_last_of(Chars, From);
@ -222,13 +222,13 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name Helpful Algorithms
/// @{
/// count - Return the number of occurrences of \arg C in the string.
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
return str().count(C);
}
/// count - Return the number of non-overlapped occurrences of \arg Str in
/// the string.
/// Return the number of non-overlapped occurrences of \p Str in the
/// string.
size_t count(StringRef Str) const {
return str().count(Str);
}
@ -237,36 +237,36 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name Substring Operations
/// @{
/// substr - Return a reference to the substring from [Start, Start + N).
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N - The number of characters to included in the substring. If N
/// \param N The number of characters to included in the substring. If \p N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \arg Start) will be returned.
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
return str().substr(Start, N);
}
/// slice - Return a reference to the substring from [Start, End).
/// Return a reference to the substring from [Start, End).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End - The index following the last character to include in the
/// substring. If this is npos, or less than \arg Start, or exceeds the
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \arg Start) will be returned.
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
/// Explicit conversion to StringRef
/// Explicit conversion to StringRef.
StringRef str() const { return StringRef(this->begin(), this->size()); }
// TODO: Make this const, if it's safe...

View File

@ -14,6 +14,7 @@
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
@ -32,22 +33,52 @@ class SmallVectorBase {
protected:
void *BeginX, *EndX, *CapacityX;
protected:
SmallVectorBase(void *FirstEl, size_t Size)
: BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
bool empty() const { return BeginX == EndX; }
};
template <typename T, unsigned N> struct SmallVectorStorage;
/// SmallVectorTemplateCommon - This is the part of SmallVectorTemplateBase
/// which does not depend on whether the type T is a POD. The extra dummy
/// template argument is used by ArrayRef to avoid unnecessarily requiring T
/// to be complete.
template <typename T, typename = void>
class SmallVectorTemplateCommon : public SmallVectorBase {
private:
template <typename, unsigned> friend struct SmallVectorStorage;
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
// don't want it to be automatically run, so we need to represent the space as
// something else. An array of char would work great, but might not be
// aligned sufficiently. Instead we use some number of union instances for
// the space, which guarantee maximal alignment.
union U {
double D;
long double LD;
long long L;
void *P;
} FirstEl;
// something else. Use an array of char of sufficient alignment.
typedef llvm::AlignedCharArrayUnion<T> U;
U FirstEl;
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:
SmallVectorBase(size_t Size)
: BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
void grow_pod(size_t MinSizeInBytes, size_t TSize) {
SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
}
/// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
@ -60,30 +91,6 @@ class SmallVectorBase {
BeginX = EndX = CapacityX = &FirstEl;
}
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(size_t MinSizeInBytes, size_t TSize);
public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
bool empty() const { return BeginX == EndX; }
};
template <typename T>
class SmallVectorTemplateCommon : public SmallVectorBase {
protected:
SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
void setEnd(T *P) { this->EndX = P; }
public:
typedef size_t size_type;
@ -677,8 +684,8 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
RHS.begin(), RHS.end());
}
/// set_size - Set the array size to \arg N, which the current array must have
/// enough capacity for.
/// Set the array size to \p N, which the current array must have enough
/// capacity for.
///
/// This does not construct or destroy any elements in the vector.
///
@ -844,6 +851,17 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
}
#endif
/// Storage for the SmallVector elements which aren't contained in
/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
/// element is in the base class. This is specialized for the N=1 and N=0 cases
/// to avoid allocating unnecessary storage.
template <typename T, unsigned N>
struct SmallVectorStorage {
typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
};
template <typename T> struct SmallVectorStorage<T, 1> {};
template <typename T> struct SmallVectorStorage<T, 0> {};
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements
/// in-place, which allows it to avoid heap allocation when the actual number of
@ -854,41 +872,23 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
///
template <typename T, unsigned N>
class SmallVector : public SmallVectorImpl<T> {
/// InlineElts - These are 'N-1' elements that are stored inline in the body
/// of the vector. The extra '1' element is stored in SmallVectorImpl.
typedef typename SmallVectorImpl<T>::U U;
enum {
// MinUs - The number of U's require to cover N T's.
MinUs = (static_cast<unsigned int>(sizeof(T))*N +
static_cast<unsigned int>(sizeof(U)) - 1) /
static_cast<unsigned int>(sizeof(U)),
// NumInlineEltsElts - The number of elements actually in this array. There
// is already one in the parent class, and we have to round up to avoid
// having a zero-element array.
NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
// NumTsAvailable - The number of T's we actually have space for, which may
// be more than N due to rounding.
NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
static_cast<unsigned int>(sizeof(T))
};
U InlineElts[NumInlineEltsElts];
/// Storage - Inline space for elements which aren't stored in the base class.
SmallVectorStorage<T, N> Storage;
public:
SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector() : SmallVectorImpl<T>(N) {
}
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(NumTsAvailable) {
: SmallVectorImpl<T>(N) {
this->assign(Size, Value);
}
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
this->append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
}
@ -899,7 +899,7 @@ class SmallVector : public SmallVectorImpl<T> {
}
#if LLVM_USE_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
@ -912,48 +912,6 @@ class SmallVector : public SmallVectorImpl<T> {
};
/// Specialize SmallVector at N=0. This specialization guarantees
/// that it can be instantiated at an incomplete T if none of its
/// members are required.
template <typename T>
class SmallVector<T,0> : public SmallVectorImpl<T> {
public:
SmallVector() : SmallVectorImpl<T>(0) {
}
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(0) {
this->assign(Size, Value);
}
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
this->append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
}
const SmallVector &operator=(const SmallVector &RHS) {
SmallVectorImpl<T>::operator=(RHS);
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(0) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
const SmallVector &operator=(SmallVector &&RHS) {
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
#endif
};
template<typename T, unsigned N>
static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
return X.capacity_in_bytes();

View File

@ -158,7 +158,7 @@ struct SparseBitVectorElement
&& "Word Position outside of element");
// Mask off previous bits.
Copy &= ~0L << BitPos;
Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
@ -262,6 +262,22 @@ struct SparseBitVectorElement
}
};
template <unsigned ElementSize>
struct ilist_traits<SparseBitVectorElement<ElementSize> >
: public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
typedef SparseBitVectorElement<ElementSize> Element;
Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
static void destroySentinel(Element *) {}
Element *provideInitialHead() const { return createSentinel(); }
Element *ensureHead(Element *) const { return createSentinel(); }
static void noteHead(Element *, Element *) {}
private:
mutable ilist_half_node<Element> Sentinel;
};
template <unsigned ElementSize = 128>
class SparseBitVector {
typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;

View File

@ -110,9 +110,9 @@ struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
/// For sets that may grow to thousands of elements, SparseT should be set to
/// uint16_t or uint32_t.
///
/// @param ValueT The type of objects in the set.
/// @param KeyFunctorT A functor that computes an unsigned index from KeyT.
/// @param SparseT An unsigned integer type. See above.
/// @tparam ValueT The type of objects in the set.
/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
/// @tparam SparseT An unsigned integer type. See above.
///
template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
@ -128,8 +128,8 @@ class SparseSet {
// Disable copy construction and assignment.
// This data structure is not meant to be used that way.
SparseSet(const SparseSet&); // DO NOT IMPLEMENT.
SparseSet &operator=(const SparseSet&); // DO NOT IMPLEMENT.
SparseSet(const SparseSet&) LLVM_DELETED_FUNCTION;
SparseSet &operator=(const SparseSet&) LLVM_DELETED_FUNCTION;
public:
typedef ValueT value_type;

View File

@ -21,7 +21,7 @@ namespace llvm {
template<typename T> class SmallVectorImpl;
/// hexdigit - Return the hexadecimal character for the
/// given number \arg X (which should be less than 16).
/// given number \p X (which should be less than 16).
static inline char hexdigit(unsigned X, bool LowerCase = false) {
const char HexChar = LowerCase ? 'a' : 'A';
return X < 10 ? '0' + X : HexChar + X - 10;
@ -125,10 +125,29 @@ void SplitString(StringRef Source,
// X*33+c -> X*33^c
static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
for (unsigned i = 0, e = Str.size(); i != e; ++i)
Result = Result * 33 + Str[i];
Result = Result * 33 + (unsigned char)Str[i];
return Result;
}
/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
static inline StringRef getOrdinalSuffix(unsigned Val) {
// It is critically important that we do this perfectly for
// user-written sequences with over 100 elements.
switch (Val % 100) {
case 11:
case 12:
case 13:
return "th";
default:
switch (Val % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
}
} // End llvm namespace
#endif

View File

@ -138,7 +138,7 @@ namespace llvm {
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \arg RHS.
/// is lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
@ -205,13 +205,13 @@ namespace llvm {
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \arg Prefix.
/// Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
}
/// endswith - Check if this string ends with the given \arg Suffix.
/// Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
@ -221,9 +221,9 @@ namespace llvm {
/// @name String Searching
/// @{
/// find - Search for the first character \arg C in the string.
/// Search for the first character \p C in the string.
///
/// \return - The index of the first occurrence of \arg C, or npos if not
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
for (size_t i = min(From, Length), e = Length; i != e; ++i)
@ -232,15 +232,15 @@ namespace llvm {
return npos;
}
/// find - Search for the first string \arg Str in the string.
/// Search for the first string \p Str in the string.
///
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const;
/// rfind - Search for the last character \arg C in the string.
/// Search for the last character \p C in the string.
///
/// \return - The index of the last occurrence of \arg C, or npos if not
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = npos) const {
From = min(From, Length);
@ -253,61 +253,61 @@ namespace llvm {
return npos;
}
/// rfind - Search for the last string \arg Str in the string.
/// Search for the last string \p Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const;
/// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find.
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
size_type find_first_of(char C, size_t From = 0) const {
return find(C, From);
}
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_first_of(StringRef Chars, size_t From = 0) const;
/// find_first_not_of - Find the first character in the string that is not
/// \arg C or npos if not found.
/// Find the first character in the string that is not \p C or npos if not
/// found.
size_type find_first_not_of(char C, size_t From = 0) const;
/// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found.
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
/// find_last_of - Find the last character in the string that is \arg C, or
/// npos if not found.
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_type find_last_of(char C, size_t From = npos) const {
return rfind(C, From);
}
/// find_last_of - Find the last character in the string that is in \arg C,
/// or npos if not found.
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_last_of(StringRef Chars, size_t From = npos) const;
/// find_last_not_of - Find the last character in the string that is not
/// \arg C, or npos if not found.
/// Find the last character in the string that is not \p C, or npos if not
/// found.
size_type find_last_not_of(char C, size_t From = npos) const;
/// find_last_not_of - Find the last character in the string that is not in
/// \arg Chars, or npos if not found.
/// Find the last character in the string that is not in \p Chars, or
/// npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_last_not_of(StringRef Chars, size_t From = npos) const;
/// @}
/// @name Helpful Algorithms
/// @{
/// count - Return the number of occurrences of \arg C in the string.
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
size_t Count = 0;
for (size_t i = 0, e = Length; i != e; ++i)
@ -316,18 +316,17 @@ namespace llvm {
return Count;
}
/// count - Return the number of non-overlapped occurrences of \arg Str in
/// Return the number of non-overlapped occurrences of \p Str in
/// the string.
size_t count(StringRef Str) const;
/// getAsInteger - Parse the current string as an integer of the specified
/// radix. If Radix is specified as zero, this does radix autosensing using
/// Parse the current string as an integer of the specified radix. If
/// \p Radix is specified as zero, this does radix autosensing using
/// extended C rules: 0 is octal, 0x is hex, 0b is binary.
///
/// If the string is invalid or if only a subset of the string is valid,
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
///
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
@ -350,13 +349,12 @@ namespace llvm {
return false;
}
/// getAsInteger - Parse the current string as an integer of the
/// specified radix, or of an autosensed radix if the radix given
/// is 0. The current value in Result is discarded, and the
/// storage is changed to be wide enough to store the parsed
/// integer.
/// Parse the current string as an integer of the specified \p Radix, or of
/// an autosensed radix if the \p Radix given is 0. The current value in
/// \p Result is discarded, and the storage is changed to be wide enough to
/// store the parsed integer.
///
/// Returns true if the string does not solely consist of a valid
/// \returns true if the string does not solely consist of a valid
/// non-empty number in the appropriate base.
///
/// APInt::fromString is superficially similar but assumes the
@ -367,70 +365,70 @@ namespace llvm {
/// @name String Operations
/// @{
// lower - Convert the given ASCII string to lowercase.
// Convert the given ASCII string to lowercase.
std::string lower() const;
/// upper - Convert the given ASCII string to uppercase.
/// Convert the given ASCII string to uppercase.
std::string upper() const;
/// @}
/// @name Substring Operations
/// @{
/// substr - Return a reference to the substring from [Start, Start + N).
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N - The number of characters to included in the substring. If N
/// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \arg Start) will be returned.
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = npos) const {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
/// drop_front - Return a StringRef equal to 'this' but with the first
/// elements dropped.
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
StringRef drop_front(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
}
/// drop_back - Return a StringRef equal to 'this' but with the last
/// elements dropped.
/// Return a StringRef equal to 'this' but with the last \p N elements
/// dropped.
StringRef drop_back(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
}
/// slice - Return a reference to the substring from [Start, End).
/// Return a reference to the substring from [Start, End).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End - The index following the last character to include in the
/// substring. If this is npos, or less than \arg Start, or exceeds the
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \arg Start) will be returned.
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
Start = min(Start, Length);
End = min(max(Start, End), Length);
return StringRef(Data + Start, End - Start);
}
/// split - Split into two substrings around the first occurrence of a
/// separator character.
/// Split into two substrings around the first occurrence of a separator
/// character.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \arg Separator is not in the string, then the result is a
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
/// \return - The split substrings.
/// \param Separator The character to split on.
/// \returns The split substrings.
std::pair<StringRef, StringRef> split(char Separator) const {
size_t Idx = find(Separator);
if (Idx == npos)
@ -438,12 +436,12 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
/// split - Split into two substrings around the first occurrence of a
/// separator string.
/// Split into two substrings around the first occurrence of a separator
/// string.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \arg Separator is not in the string, then the result is a
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The string to split on.
@ -455,14 +453,13 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
/// split - Split into substrings around the occurrences of a separator
/// string.
/// Split into substrings around the occurrences of a separator string.
///
/// Each substring is stored in \arg A. If \arg MaxSplit is >= 0, at most
/// \arg MaxSplit splits are done and consequently <= \arg MaxSplit
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
/// \p MaxSplit splits are done and consequently <= \p MaxSplit
/// elements are added to A.
/// If \arg KeepEmpty is false, empty strings are not added to \arg A. They
/// still count when considering \arg MaxSplit
/// If \p KeepEmpty is false, empty strings are not added to \p A. They
/// still count when considering \p MaxSplit
/// An useful invariant is that
/// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
///
@ -474,12 +471,12 @@ namespace llvm {
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
/// rsplit - Split into two substrings around the last occurrence of a
/// separator character.
/// Split into two substrings around the last occurrence of a separator
/// character.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// minimal. If \arg Separator is not in the string, then the result is a
/// minimal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
@ -491,20 +488,20 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
/// ltrim - Return string with consecutive characters in \arg Chars starting
/// from the left removed.
/// Return string with consecutive characters in \p Chars starting from
/// the left removed.
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_front(std::min(Length, find_first_not_of(Chars)));
}
/// rtrim - Return string with consecutive characters in \arg Chars starting
/// from the right removed.
/// Return string with consecutive characters in \p Chars starting from
/// the right removed.
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
}
/// trim - Return string with consecutive characters in \arg Chars starting
/// from the left and right removed.
/// Return string with consecutive characters in \p Chars starting from
/// the left and right removed.
StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
return ltrim(Chars).rtrim(Chars);
}

View File

@ -29,8 +29,13 @@ namespace llvm {
assert(!InLang.empty());
const char *KeyStart = InLang.data();
const char *KeyEnd = KeyStart + InLang.size();
return base::insert(llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+');
if (!base::insert(Entry)) {
Entry->Destroy(base::getAllocator());
return false;
}
return true;
}
};
}

View File

@ -1,334 +0,0 @@
//===- llvm/ADT/Trie.h ---- Generic trie structure --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class defines a generic trie structure. The trie structure
// is immutable after creation, but the payload contained within it is not.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_TRIE_H
#define LLVM_ADT_TRIE_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/DOTGraphTraits.h"
#include <cassert>
#include <vector>
namespace llvm {
// FIXME:
// - Labels are usually small, maybe it's better to use SmallString
// - Should we use char* during construction?
// - Should we templatize Empty with traits-like interface?
template<class Payload>
class Trie {
friend class GraphTraits<Trie<Payload> >;
friend class DOTGraphTraits<Trie<Payload> >;
public:
class Node {
friend class Trie;
public:
typedef std::vector<Node*> NodeVectorType;
typedef typename NodeVectorType::iterator iterator;
typedef typename NodeVectorType::const_iterator const_iterator;
private:
enum QueryResult {
Same = -3,
StringIsPrefix = -2,
LabelIsPrefix = -1,
DontMatch = 0,
HaveCommonPart
};
struct NodeCmp {
bool operator() (Node* N1, Node* N2) {
return (N1->Label[0] < N2->Label[0]);
}
bool operator() (Node* N, char Id) {
return (N->Label[0] < Id);
}
};
std::string Label;
Payload Data;
NodeVectorType Children;
// Do not implement
Node(const Node&);
Node& operator=(const Node&);
inline void addEdge(Node* N) {
if (Children.empty())
Children.push_back(N);
else {
iterator I = std::lower_bound(Children.begin(), Children.end(),
N, NodeCmp());
// FIXME: no dups are allowed
Children.insert(I, N);
}
}
inline void setEdge(Node* N) {
char Id = N->Label[0];
iterator I = std::lower_bound(Children.begin(), Children.end(),
Id, NodeCmp());
assert(I != Children.end() && "Node does not exists!");
*I = N;
}
QueryResult query(const std::string& s) const {
unsigned i, l;
unsigned l1 = s.length();
unsigned l2 = Label.length();
// Find the length of common part
l = std::min(l1, l2);
i = 0;
while ((i < l) && (s[i] == Label[i]))
++i;
if (i == l) { // One is prefix of another, find who is who
if (l1 == l2)
return Same;
else if (i == l1)
return StringIsPrefix;
else
return LabelIsPrefix;
} else // s and Label have common (possible empty) part, return its length
return (QueryResult)i;
}
public:
inline explicit Node(const Payload& data, const std::string& label = ""):
Label(label), Data(data) { }
inline const Payload& data() const { return Data; }
inline void setData(const Payload& data) { Data = data; }
inline const std::string& label() const { return Label; }
#if 0
inline void dump() {
llvm::cerr << "Node: " << this << "\n"
<< "Label: " << Label << "\n"
<< "Children:\n";
for (iterator I = Children.begin(), E = Children.end(); I != E; ++I)
llvm::cerr << (*I)->Label << "\n";
}
#endif
inline Node* getEdge(char Id) {
Node* fNode = NULL;
iterator I = std::lower_bound(Children.begin(), Children.end(),
Id, NodeCmp());
if (I != Children.end() && (*I)->Label[0] == Id)
fNode = *I;
return fNode;
}
inline iterator begin() { return Children.begin(); }
inline const_iterator begin() const { return Children.begin(); }
inline iterator end () { return Children.end(); }
inline const_iterator end () const { return Children.end(); }
inline size_t size () const { return Children.size(); }
inline bool empty() const { return Children.empty(); }
inline const Node* &front() const { return Children.front(); }
inline Node* &front() { return Children.front(); }
inline const Node* &back() const { return Children.back(); }
inline Node* &back() { return Children.back(); }
};
private:
std::vector<Node*> Nodes;
Payload Empty;
inline Node* addNode(const Payload& data, const std::string label = "") {
Node* N = new Node(data, label);
Nodes.push_back(N);
return N;
}
inline Node* splitEdge(Node* N, char Id, size_t index) {
Node* eNode = N->getEdge(Id);
assert(eNode && "Node doesn't exist");
const std::string &l = eNode->Label;
assert(index > 0 && index < l.length() && "Trying to split too far!");
std::string l1 = l.substr(0, index);
std::string l2 = l.substr(index);
Node* nNode = addNode(Empty, l1);
N->setEdge(nNode);
eNode->Label = l2;
nNode->addEdge(eNode);
return nNode;
}
// Do not implement
Trie(const Trie&);
Trie& operator=(const Trie&);
public:
inline explicit Trie(const Payload& empty):Empty(empty) {
addNode(Empty);
}
inline ~Trie() {
for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
delete Nodes[i];
}
inline Node* getRoot() const { return Nodes[0]; }
bool addString(const std::string& s, const Payload& data);
const Payload& lookup(const std::string& s) const;
};
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template<class Payload>
bool Trie<Payload>::addString(const std::string& s, const Payload& data) {
Node* cNode = getRoot();
Node* tNode = NULL;
std::string s1(s);
while (tNode == NULL) {
char Id = s1[0];
if (Node* nNode = cNode->getEdge(Id)) {
typename Node::QueryResult r = nNode->query(s1);
switch (r) {
case Node::Same:
case Node::StringIsPrefix:
// Currently we don't allow to have two strings in the trie one
// being a prefix of another. This should be fixed.
assert(0 && "FIXME!");
return false;
case Node::DontMatch:
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;
break;
default:
nNode = splitEdge(cNode, Id, r);
tNode = addNode(data, s1.substr(r));
nNode->addEdge(tNode);
}
} else {
tNode = addNode(data, s1);
cNode->addEdge(tNode);
}
}
return true;
}
template<class Payload>
const Payload& Trie<Payload>::lookup(const std::string& s) const {
Node* cNode = getRoot();
Node* tNode = NULL;
std::string s1(s);
while (tNode == NULL) {
char Id = s1[0];
if (Node* nNode = cNode->getEdge(Id)) {
typename Node::QueryResult r = nNode->query(s1);
switch (r) {
case Node::Same:
tNode = nNode;
break;
case Node::StringIsPrefix:
return Empty;
case Node::DontMatch:
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;
break;
default:
return Empty;
}
} else
return Empty;
}
return tNode->data();
}
template<class Payload>
struct GraphTraits<Trie<Payload> > {
typedef Trie<Payload> TrieType;
typedef typename TrieType::Node NodeType;
typedef typename NodeType::iterator ChildIteratorType;
static inline NodeType *getEntryNode(const TrieType& T) {
return T.getRoot();
}
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
typedef typename std::vector<NodeType*>::const_iterator nodes_iterator;
static inline nodes_iterator nodes_begin(const TrieType& G) {
return G.Nodes.begin();
}
static inline nodes_iterator nodes_end(const TrieType& G) {
return G.Nodes.end();
}
};
template<class Payload>
struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
typedef typename Trie<Payload>::Node NodeType;
typedef typename GraphTraits<Trie<Payload> >::ChildIteratorType EdgeIter;
static std::string getGraphName(const Trie<Payload>& T) {
return "Trie";
}
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
if (T.getRoot() == Node)
return "<Root>";
else
return Node->label();
}
static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
NodeType* N = *I;
return N->label().substr(0, 1);
}
static std::string getNodeAttributes(const NodeType* Node,
const Trie<Payload>& T) {
if (Node->data() != T.Empty)
return "color=blue";
return "";
}
};
} // end of llvm namespace
#endif // LLVM_ADT_TRIE_H

View File

@ -65,7 +65,9 @@ class Triple {
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil // amdil: amd IL
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
enum VendorType {
UnknownVendor,
@ -74,7 +76,9 @@ class Triple {
PC,
SCEI,
BGP,
BGQ
BGQ,
Freescale,
IBM
};
enum OSType {
UnknownOS,
@ -99,7 +103,8 @@ class Triple {
RTEMS,
NativeClient,
CNK, // BG/P Compute-Node Kernel
Bitrig
Bitrig,
AIX
};
enum EnvironmentType {
UnknownEnvironment,
@ -109,7 +114,8 @@ class Triple {
GNUEABIHF,
EABI,
MachO,
ANDROIDEABI
Android,
ELF
};
private:
@ -341,7 +347,7 @@ class Triple {
/// to a known type.
void setEnvironment(EnvironmentType Kind);
/// setTriple - Set all components to the new triple \arg Str.
/// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
/// setArchName - Set the architecture (first) component of the
@ -392,11 +398,10 @@ class Triple {
/// @name Static helpers for IDs.
/// @{
/// getArchTypeName - Get the canonical name for the \arg Kind
/// architecture.
/// getArchTypeName - Get the canonical name for the \p Kind architecture.
static const char *getArchTypeName(ArchType Kind);
/// getArchTypePrefix - Get the "prefix" canonical name for the \arg Kind
/// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
/// architecture. This is the prefix used by the architecture specific
/// builtins, and is suitable for passing to \see
/// Intrinsic::getIntrinsicForGCCBuiltin().
@ -404,15 +409,13 @@ class Triple {
/// \return - The architecture prefix, or 0 if none is defined.
static const char *getArchTypePrefix(ArchType Kind);
/// getVendorTypeName - Get the canonical name for the \arg Kind
/// vendor.
/// getVendorTypeName - Get the canonical name for the \p Kind vendor.
static const char *getVendorTypeName(VendorType Kind);
/// getOSTypeName - Get the canonical name for the \arg Kind operating
/// system.
/// getOSTypeName - Get the canonical name for the \p Kind operating system.
static const char *getOSTypeName(OSType Kind);
/// getEnvironmentTypeName - Get the canonical name for the \arg Kind
/// getEnvironmentTypeName - Get the canonical name for the \p Kind
/// environment.
static const char *getEnvironmentTypeName(EnvironmentType Kind);
@ -424,11 +427,6 @@ class Triple {
/// architecture name (e.g., "x86").
static ArchType getArchTypeForLLVMName(StringRef Str);
/// getArchTypeForDarwinArchName - Get the architecture type for a "Darwin"
/// architecture name, for example as accepted by "gcc -arch" (see also
/// arch(3)).
static ArchType getArchTypeForDarwinArchName(StringRef Str);
/// @}
};

View File

@ -44,7 +44,7 @@ namespace llvm {
/// itself, and renders as an empty string. This can be returned from APIs to
/// effectively nullify any concatenations performed on the result.
///
/// \b Implementation \n
/// \b Implementation
///
/// Given the nature of a Twine, it is not possible for the Twine's
/// concatenation method to construct interior nodes; the result must be
@ -67,7 +67,7 @@ namespace llvm {
///
/// These invariants are check by \see isValid().
///
/// \b Efficiency Considerations \n
/// \b Efficiency Considerations
///
/// The Twine is designed to yield efficient and small code for common
/// situations. For this reason, the concat() method is inlined so that
@ -303,37 +303,37 @@ namespace llvm {
LHS.character = static_cast<char>(Val);
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(unsigned Val)
: LHSKind(DecUIKind), RHSKind(EmptyKind) {
LHS.decUI = Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(int Val)
: LHSKind(DecIKind), RHSKind(EmptyKind) {
LHS.decI = Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val)
: LHSKind(DecULKind), RHSKind(EmptyKind) {
LHS.decUL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long &Val)
: LHSKind(DecLKind), RHSKind(EmptyKind) {
LHS.decL = &Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val)
: LHSKind(DecULLKind), RHSKind(EmptyKind) {
LHS.decULL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long long &Val)
: LHSKind(DecLLKind), RHSKind(EmptyKind) {
LHS.decLL = &Val;
@ -370,7 +370,7 @@ namespace llvm {
/// @name Numeric Conversions
/// @{
// Construct a twine to print \arg Val as an unsigned hexadecimal integer.
// Construct a twine to print \p Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
Child LHS, RHS;
LHS.uHex = &Val;
@ -447,17 +447,17 @@ namespace llvm {
/// The returned StringRef's size does not include the null terminator.
StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
/// print - Write the concatenated string represented by this twine to the
/// stream \arg OS.
/// Write the concatenated string represented by this twine to the
/// stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Dump the concatenated string represented by this twine to stderr.
/// Dump the concatenated string represented by this twine to stderr.
void dump() const;
/// print - Write the representation of this twine to the stream \arg OS.
/// Write the representation of this twine to the stream \p OS.
void printRepr(raw_ostream &OS) const;
/// dumpRepr - Dump the representation of this twine to stderr.
/// Dump the representation of this twine to stderr.
void dumpRepr() const;
/// @}

View File

@ -80,8 +80,8 @@ class ValueMap {
typedef typename Config::ExtraData ExtraData;
MapT Map;
ExtraData Data;
ValueMap(const ValueMap&); // DO NOT IMPLEMENT
ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;

View File

@ -38,6 +38,7 @@
#ifndef LLVM_ADT_ILIST_H
#define LLVM_ADT_ILIST_H
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@ -331,8 +332,8 @@ class iplist : public Traits {
// No fundamental reason why iplist can't be copyable, but the default
// copy/copy-assign won't do.
iplist(const iplist &); // do not implement
void operator=(const iplist &); // do not implement
iplist(const iplist &) LLVM_DELETED_FUNCTION;
void operator=(const iplist &) LLVM_DELETED_FUNCTION;
public:
typedef NodeTy *pointer;

View File

@ -0,0 +1,41 @@
//===--------- llvm/AddressingMode.h - Addressing Mode -------*- 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 addressing mode data structures which are shared
// between LSR and a number of places in the codegen.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADDRESSING_MODE_H
#define LLVM_ADDRESSING_MODE_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class GlobalValue;
/// AddrMode - This represents an addressing mode of:
/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
/// If BaseGV is null, there is no BaseGV.
/// If BaseOffs is zero, there is no base offset.
/// If HasBaseReg is false, there is no base register.
/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
/// no scale.
///
struct AddrMode {
GlobalValue *BaseGV;
int64_t BaseOffs;
bool HasBaseReg;
int64_t Scale;
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
} // End llvm namespace
#endif

View File

@ -45,7 +45,8 @@ namespace llvm {
class LoadInst;
class StoreInst;
class VAArgInst;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Pass;
class AnalysisUsage;
class MemTransferInst;
@ -54,7 +55,8 @@ class DominatorTree;
class AliasAnalysis {
protected:
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
private:
AliasAnalysis *AA; // Previous Alias Analysis to chain to.
@ -73,7 +75,7 @@ class AliasAnalysis {
public:
static char ID; // Class identification, replacement for typeinfo
AliasAnalysis() : TD(0), AA(0) {}
AliasAnalysis() : TD(0), TLI(0), AA(0) {}
virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
@ -81,12 +83,17 @@ class AliasAnalysis {
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
/// getTargetData - Return a pointer to the current TargetData object, or
/// null if no TargetData object is available.
/// getDataLayout - Return a pointer to the current DataLayout object, or
/// null if no DataLayout object is available.
///
const TargetData *getTargetData() const { return TD; }
const DataLayout *getDataLayout() const { return TD; }
/// getTypeStoreSize - Return the TargetData store size for the given type,
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
/// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(Type *Ty);
@ -187,6 +194,11 @@ class AliasAnalysis {
return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
}
/// isNoAlias - A convenience wrapper.
bool isNoAlias(const Value *V1, const Value *V2) {
return isNoAlias(Location(V1), Location(V2));
}
/// isMustAlias - A convenience wrapper.
bool isMustAlias(const Location &LocA, const Location &LocB) {
return alias(LocA, LocB) == MustAlias;

View File

@ -109,7 +109,6 @@ class AliasSet : public ilist_node<AliasSet> {
PointerRec *PtrList, **PtrListEnd; // Doubly linked list of nodes.
AliasSet *Forward; // Forwarding pointer.
AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction> > UnknownInsts;
@ -226,8 +225,8 @@ class AliasSet : public ilist_node<AliasSet> {
AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
}
AliasSet(const AliasSet &AS); // do not implement
void operator=(const AliasSet &AS); // do not implement
AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
PointerRec *getSomePointer() const {
return PtrList;

View File

@ -28,11 +28,14 @@ class raw_ostream;
///
/// This is a function analysis pass which provides information on the relative
/// probabilities of each "edge" in the function's CFG where such an edge is
/// defined by a pair of basic blocks. The probability for a given block and
/// a successor block are always relative to the probabilities of the other
/// successor blocks. Another way of looking at it is that the probabilities
/// for a given block B and each of its successors should sum to exactly
/// one (100%).
/// defined by a pair (PredBlock and an index in the successors). The
/// probability of an edge from one block is always relative to the
/// probabilities of other edges from the block. The probabilites of all edges
/// from a block sum to exactly one (100%).
/// We use a pair (PredBlock and an index in the successors) to uniquely
/// identify an edge, since we can have multiple edges from Src to Dst.
/// As an example, we can have a switch which jumps to Dst with value 0 and
/// value 10.
class BranchProbabilityInfo : public FunctionPass {
public:
static char ID;
@ -51,6 +54,12 @@ class BranchProbabilityInfo : public FunctionPass {
/// (0%) and one (100%) of this edge executing, relative to other edges
/// leaving the 'Src' block. The returned probability is never zero, and can
/// only be one if the source block has only one successor.
BranchProbability getEdgeProbability(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the probability of going from Src to Dst.
///
/// It returns the sum of all probabilities for edges from Src to Dst.
BranchProbability getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const;
@ -74,25 +83,34 @@ class BranchProbabilityInfo : public FunctionPass {
raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Get the raw edge weight calculated for the block pair.
/// \brief Get the raw edge weight calculated for the edge.
///
/// This returns the raw edge weight. It is guaranteed to fall between 1 and
/// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
/// This interface should be very carefully, and primarily by routines that
/// are updating the analysis by later calling setEdgeWeight.
uint32_t getEdgeWeight(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the raw edge weight calculated for the block pair.
///
/// This returns the sum of all raw edge weights from Src to Dst.
/// It is guaranteed to fall between 1 and UINT32_MAX.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Set the raw edge weight for the block pair.
/// \brief Set the raw edge weight for a given edge.
///
/// This allows a pass to explicitly set the edge weight for a block. It can
/// This allows a pass to explicitly set the edge weight for an edge. It can
/// be used when updating the CFG to update and preserve the branch
/// probability information. Read the implementation of how these edge
/// weights are calculated carefully before using!
void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors,
uint32_t Weight);
private:
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
// Since we allow duplicate edges from one basic block to another, we use
// a pair (PredBlock and an index in the successors) to specify an edge.
typedef std::pair<const BasicBlock *, unsigned> Edge;
// Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of

View File

@ -185,9 +185,9 @@ class CallGraphNode {
/// in the CalledFunctions array of this or other CallGraphNodes.
unsigned NumReferences;
CallGraphNode(const CallGraphNode &); // DO NOT IMPLEMENT
void operator=(const CallGraphNode &); // DO NOT IMPLEMENT
CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void DropRef() { --NumReferences; }
void AddRef() { ++NumReferences; }
public:

View File

@ -46,7 +46,7 @@ namespace llvm {
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
virtual bool shouldExplore(Use *U) = 0;
virtual bool shouldExplore(Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking

View File

@ -22,11 +22,11 @@ namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class TargetData;
class DataLayout;
class Value;
/// \brief Check whether an instruction is likely to be "free" when lowered.
bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
/// \brief Check whether a call will lower to something small.
///
@ -85,10 +85,10 @@ namespace llvm {
NumRets(0) {}
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
/// \brief Add information about a function to the current state.
void analyzeFunction(Function *F, const TargetData *TD = 0);
void analyzeFunction(Function *F, const DataLayout *TD = 0);
};
}

View File

@ -12,7 +12,7 @@
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
// TargetData information. These functions cannot go in VMCore due to library
// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
@ -24,7 +24,7 @@ namespace llvm {
class Constant;
class ConstantExpr;
class Instruction;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Function;
class Type;
@ -36,14 +36,14 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
Constant *ConstantFoldInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is
/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@ -54,7 +54,7 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
@ -63,7 +63,7 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
@ -75,7 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
Constant *ConstantFoldLoadFromConstPtr(Constant *C, const TargetData *TD = 0);
Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout *TD = 0);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the

View File

@ -0,0 +1,885 @@
//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DependenceAnalysis is an LLVM pass that analyses dependences between memory
// accesses. Currently, it is an implementation of the approach described in
//
// Practical Dependence Testing
// Goff, Kennedy, Tseng
// PLDI 1991
//
// There's a single entry point that analyzes the dependence between a pair
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// Plausible changes:
// Return a set of more precise dependences instead of just one dependence
// summarizing all.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/ADT/SmallBitVector.h"
namespace llvm {
class AliasAnalysis;
class Loop;
class LoopInfo;
class ScalarEvolution;
class SCEV;
class SCEVConstant;
class raw_ostream;
/// Dependence - This class represents a dependence between two memory
/// memory references in a function. It contains minimal information and
/// is used in the very common situation where the compiler is unable to
/// determine anything beyond the existence of a dependence; that is, it
/// represents a confused dependence (see also FullDependence). In most
/// cases (for output, flow, and anti dependences), the dependence implies
/// an ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class Dependence {
public:
Dependence(const Instruction *Source,
const Instruction *Destination) :
Src(Source), Dst(Destination) {}
virtual ~Dependence() {}
/// Dependence::DVEntry - Each level in the distance/direction vector
/// has a direction (or perhaps a union of several directions), and
/// perhaps a distance.
struct DVEntry {
enum { NONE = 0,
LT = 1,
EQ = 2,
LE = 3,
GT = 4,
NE = 5,
GE = 6,
ALL = 7 };
unsigned char Direction : 3; // Init to ALL, then refine.
bool Scalar : 1; // Init to true.
bool PeelFirst : 1; // Peeling the first iteration will break dependence.
bool PeelLast : 1; // Peeling the last iteration will break the dependence.
bool Splitable : 1; // Splitting the loop will break dependence.
const SCEV *Distance; // NULL implies no distance available.
DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false),
PeelLast(false), Splitable(false), Distance(NULL) { }
};
/// getSrc - Returns the source instruction for this dependence.
///
const Instruction *getSrc() const { return Src; }
/// getDst - Returns the destination instruction for this dependence.
///
const Instruction *getDst() const { return Dst; }
/// isInput - Returns true if this is an input dependence.
///
bool isInput() const;
/// isOutput - Returns true if this is an output dependence.
///
bool isOutput() const;
/// isFlow - Returns true if this is a flow (aka true) dependence.
///
bool isFlow() const;
/// isAnti - Returns true if this is an anti dependence.
///
bool isAnti() const;
/// isOrdered - Returns true if dependence is Output, Flow, or Anti
///
bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
/// isUnordered - Returns true if dependence is Input
///
bool isUnordered() const { return isInput(); }
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
virtual bool isLoopIndependent() const { return true; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
virtual bool isConfused() const { return true; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
virtual bool isConsistent() const { return false; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
virtual unsigned getLevels() const { return 0; }
/// getDirection - Returns the direction associated with a particular
/// level.
virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
virtual const SCEV *getDistance(unsigned Level) const { return NULL; }
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
virtual bool isPeelFirst(unsigned Level) const { return false; }
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
virtual bool isPeelLast(unsigned Level) const { return false; }
/// isSplitable - Returns true if splitting this loop will break
/// the dependence.
virtual bool isSplitable(unsigned Level) const { return false; }
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
virtual bool isScalar(unsigned Level) const;
/// dump - For debugging purposes, dumps a dependence to OS.
///
void dump(raw_ostream &OS) const;
private:
const Instruction *Src, *Dst;
friend class DependenceAnalysis;
};
/// FullDependence - This class represents a dependence between two memory
/// references in a function. It contains detailed information about the
/// dependence (direction vectors, etc) and is used when the compiler is
/// able to accurately analyze the interaction of the references; that is,
/// it is not a confused dependence (see Dependence). In most cases
/// (for output, flow, and anti dependences), the dependence implies an
/// ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class FullDependence : public Dependence {
public:
FullDependence(const Instruction *Src,
const Instruction *Dst,
bool LoopIndependent,
unsigned Levels);
~FullDependence() {
delete DV;
}
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
bool isLoopIndependent() const { return LoopIndependent; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
bool isConfused() const { return false; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
bool isConsistent() const { return Consistent; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
unsigned getLevels() const { return Levels; }
/// getDirection - Returns the direction associated with a particular
/// level.
unsigned getDirection(unsigned Level) const;
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
const SCEV *getDistance(unsigned Level) const;
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
bool isPeelFirst(unsigned Level) const;
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
bool isPeelLast(unsigned Level) const;
/// isSplitable - Returns true if splitting the loop will break
/// the dependence.
bool isSplitable(unsigned Level) const;
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
bool isScalar(unsigned Level) const;
private:
unsigned short Levels;
bool LoopIndependent;
bool Consistent; // Init to true, then refine.
DVEntry *DV;
friend class DependenceAnalysis;
};
/// DependenceAnalysis - This class is the main dependence-analysis driver.
///
class DependenceAnalysis : public FunctionPass {
void operator=(const DependenceAnalysis &); // do not implement
DependenceAnalysis(const DependenceAnalysis &); // do not implement
public:
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
/// FullDependence) with as much information as can be gleaned.
/// The flag PossiblyLoopIndependent should be set by the caller
/// if it appears that control flow can reach from Src to Dst
/// without traversing a loop back edge.
Dependence *depends(const Instruction *Src,
const Instruction *Dst,
bool PossiblyLoopIndependent);
/// getSplitIteration - Give a dependence that's splitable at some
/// particular level, return the iteration that should be used to split
/// the loop.
///
/// Generally, the dependence analyzer will be used to build
/// a dependence graph for a function (basically a map from instructions
/// to dependences). Looking for cycles in the graph shows us loops
/// that cannot be trivially vectorized/parallelized.
///
/// We can try to improve the situation by examining all the dependences
/// that make up the cycle, looking for ones we can break.
/// Sometimes, peeling the first or last iteration of a loop will break
/// dependences, and there are flags for those possibilities.
/// Sometimes, splitting a loop at some other iteration will do the trick,
/// and we've got a flag for that case. Rather than waste the space to
/// record the exact iteration (since we rarely know), we provide
/// a method that calculates the iteration. It's a drag that it must work
/// from scratch, but wonderful in that it's possible.
///
/// Here's an example:
///
/// for (i = 0; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// There's a loop-carried flow dependence from the store to the load,
/// found by the weak-crossing SIV test. The dependence will have a flag,
/// indicating that the dependence can be broken by splitting the loop.
/// Calling getSplitIteration will return 5.
/// Splitting the loop breaks the dependence, like so:
///
/// for (i = 0; i <= 5; i++)
/// A[i] = ...
/// ... = A[11 - i]
/// for (i = 6; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// breaks the dependence and allows us to vectorize/parallelize
/// both loops.
const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level);
private:
AliasAnalysis *AA;
ScalarEvolution *SE;
LoopInfo *LI;
Function *F;
/// Subscript - This private struct represents a pair of subscripts from
/// a pair of potentially multi-dimensional array references. We use a
/// vector of them to guide subscript partitioning.
struct Subscript {
const SCEV *Src;
const SCEV *Dst;
enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
SmallBitVector Loops;
SmallBitVector GroupLoops;
SmallBitVector Group;
};
struct CoefficientInfo {
const SCEV *Coeff;
const SCEV *PosPart;
const SCEV *NegPart;
const SCEV *Iterations;
};
struct BoundInfo {
const SCEV *Iterations;
const SCEV *Upper[8];
const SCEV *Lower[8];
unsigned char Direction;
unsigned char DirSet;
};
/// Constraint - This private class represents a constraint, as defined
/// in the paper
///
/// Practical Dependence Testing
/// Goff, Kennedy, Tseng
/// PLDI 1991
///
/// There are 5 kinds of constraint, in a hierarchy.
/// 1) Any - indicates no constraint, any dependence is possible.
/// 2) Line - A line ax + by = c, where a, b, and c are parameters,
/// representing the dependence equation.
/// 3) Distance - The value d of the dependence distance;
/// 4) Point - A point <x, y> representing the dependence from
/// iteration x to iteration y.
/// 5) Empty - No dependence is possible.
class Constraint {
private:
enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
ScalarEvolution *SE;
const SCEV *A;
const SCEV *B;
const SCEV *C;
const Loop *AssociatedLoop;
public:
/// isEmpty - Return true if the constraint is of kind Empty.
bool isEmpty() const { return Kind == Empty; }
/// isPoint - Return true if the constraint is of kind Point.
bool isPoint() const { return Kind == Point; }
/// isDistance - Return true if the constraint is of kind Distance.
bool isDistance() const { return Kind == Distance; }
/// isLine - Return true if the constraint is of kind Line.
/// Since Distance's can also be represented as Lines, we also return
/// true if the constraint is of kind Distance.
bool isLine() const { return Kind == Line || Kind == Distance; }
/// isAny - Return true if the constraint is of kind Any;
bool isAny() const { return Kind == Any; }
/// getX - If constraint is a point <X, Y>, returns X.
/// Otherwise assert.
const SCEV *getX() const;
/// getY - If constraint is a point <X, Y>, returns Y.
/// Otherwise assert.
const SCEV *getY() const;
/// getA - If constraint is a line AX + BY = C, returns A.
/// Otherwise assert.
const SCEV *getA() const;
/// getB - If constraint is a line AX + BY = C, returns B.
/// Otherwise assert.
const SCEV *getB() const;
/// getC - If constraint is a line AX + BY = C, returns C.
/// Otherwise assert.
const SCEV *getC() const;
/// getD - If constraint is a distance, returns D.
/// Otherwise assert.
const SCEV *getD() const;
/// getAssociatedLoop - Returns the loop associated with this constraint.
const Loop *getAssociatedLoop() const;
/// setPoint - Change a constraint to Point.
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
/// setLine - Change a constraint to Line.
void setLine(const SCEV *A, const SCEV *B,
const SCEV *C, const Loop *CurrentLoop);
/// setDistance - Change a constraint to Distance.
void setDistance(const SCEV *D, const Loop *CurrentLoop);
/// setEmpty - Change a constraint to Empty.
void setEmpty();
/// setAny - Change a constraint to Any.
void setAny(ScalarEvolution *SE);
/// dump - For debugging purposes. Dumps the constraint
/// out to OS.
void dump(raw_ostream &OS) const;
};
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
/// instructions and establishes their shared loops. Sets the variables
/// CommonLevels, SrcLevels, and MaxLevels.
/// The source and destination instructions needn't be contained in the same
/// loop. The routine establishNestingLevels finds the level of most deeply
/// nested loop that contains them both, CommonLevels. An instruction that's
/// not contained in a loop is at level = 0. MaxLevels is equal to the level
/// of the source plus the level of the destination, minus CommonLevels.
/// This lets us allocate vectors MaxLevels in length, with room for every
/// distinct loop referenced in both the source and destination subscripts.
/// The variable SrcLevels is the nesting depth of the source instruction.
/// It's used to help calculate distinct loops referenced by the destination.
/// Here's the map from loops to levels:
/// 0 - unused
/// 1 - outermost common loop
/// ... - other common loops
/// CommonLevels - innermost common loop
/// ... - loops containing Src but not Dst
/// SrcLevels - innermost loop containing Src but not Dst
/// ... - loops containing Dst but not Src
/// MaxLevels - innermost loop containing Dst but not Src
/// Consider the follow code fragment:
/// for (a = ...) {
/// for (b = ...) {
/// for (c = ...) {
/// for (d = ...) {
/// A[] = ...;
/// }
/// }
/// for (e = ...) {
/// for (f = ...) {
/// for (g = ...) {
/// ... = A[];
/// }
/// }
/// }
/// }
/// }
/// If we're looking at the possibility of a dependence between the store
/// to A (the Src) and the load from A (the Dst), we'll note that they
/// have 2 loops in common, so CommonLevels will equal 2 and the direction
/// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
/// A map from loop names to level indices would look like
/// a - 1
/// b - 2 = CommonLevels
/// c - 3
/// d - 4 = SrcLevels
/// e - 5
/// f - 6
/// g - 7 = MaxLevels
void establishNestingLevels(const Instruction *Src,
const Instruction *Dst);
unsigned CommonLevels, SrcLevels, MaxLevels;
/// mapSrcLoop - Given one of the loops containing the source, return
/// its level index in our numbering scheme.
unsigned mapSrcLoop(const Loop *SrcLoop) const;
/// mapDstLoop - Given one of the loops containing the destination,
/// return its level index in our numbering scheme.
unsigned mapDstLoop(const Loop *DstLoop) const;
/// isLoopInvariant - Returns true if Expression is loop invariant
/// in LoopNest.
bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
/// removeMatchingExtensions - Examines a subscript pair.
/// If the source and destination are identically sign (or zero)
/// extended, it strips off the extension in an effort to
/// simplify the actual analysis.
void removeMatchingExtensions(Subscript *Pair);
/// collectCommonLoops - Finds the set of loops from the LoopNest that
/// have a level <= CommonLevels and are referred to by the SCEV Expression.
void collectCommonLoops(const SCEV *Expression,
const Loop *LoopNest,
SmallBitVector &Loops) const;
/// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
/// linear. Collect the set of loops mentioned by Src.
bool checkSrcSubscript(const SCEV *Src,
const Loop *LoopNest,
SmallBitVector &Loops);
/// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
/// linear. Collect the set of loops mentioned by Dst.
bool checkDstSubscript(const SCEV *Dst,
const Loop *LoopNest,
SmallBitVector &Loops);
/// isKnownPredicate - Compare X and Y using the predicate Pred.
/// Basically a wrapper for SCEV::isKnownPredicate,
/// but tries harder, especially in the presence of sign and zero
/// extensions and symbolics.
bool isKnownPredicate(ICmpInst::Predicate Pred,
const SCEV *X,
const SCEV *Y) const;
/// collectUpperBound - All subscripts are the same type (on my machine,
/// an i64). The loop bound may be a smaller type. collectUpperBound
/// find the bound, if available, and zero extends it to the Type T.
/// (I zero extend since the bound should always be >= 0.)
/// If no upper bound is available, return NULL.
const SCEV *collectUpperBound(const Loop *l, Type *T) const;
/// collectConstantUpperBound - Calls collectUpperBound(), then
/// attempts to cast it to SCEVConstant. If the cast fails,
/// returns NULL.
const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;
/// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
/// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
/// Collects the associated loops in a set.
Subscript::ClassificationKind classifyPair(const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
const Loop *DstLoopNest,
SmallBitVector &Loops);
/// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testZIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j], where
/// i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction vector entry and, when possible,
/// the distance vector entry.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testSIV(const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
/// where i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// With minor algebra, this test can also be used for things like
/// [c1 + a1*i + a2*j][c2].
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Marks the Result as inconsistent.
bool testRDIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
/// Returns true if dependence disproved.
/// Can sometimes refine direction vectors.
bool testMIV(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
/// for dependence.
/// Things of the form [c1 + a*i] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction and distance.
bool strongSIVtest(const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2 - a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// Marks the dependence as splitable.
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// ExactSIVtest - Tests the SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
bool exactSIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroDstSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroSrcSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// exactRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that symbolicRDIVtest doesn't,
/// and vice versa.
bool exactRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop,
FullDependence &Result) const;
/// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that exactRDIVtest doesn't,
/// and vice versa. Can also be used as a backup for
/// ordinary SIV tests.
bool symbolicRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop) const;
/// gcdMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Can sometimes disprove the equal direction for 1 or more loops.
// Can handle some symbolics that even the SIV tests don't get,
/// so we use it as a backup for everything.
bool gcdMIVtest(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Computes directions.
bool banerjeeMIVtest(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// collectCoefficientInfo - Walks through the subscript,
/// collecting each coefficient, the associated loop bounds,
/// and recording its positive and negative parts for later use.
CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
bool SrcFlag,
const SCEV *&Constant) const;
/// getPositivePart - X^+ = max(X, 0).
///
const SCEV *getPositivePart(const SCEV *X) const;
/// getNegativePart - X^- = min(X, 0).
///
const SCEV *getNegativePart(const SCEV *X) const;
/// getLowerBound - Looks through all the bounds info and
/// computes the lower bound given the current direction settings
/// at each level.
const SCEV *getLowerBound(BoundInfo *Bound) const;
/// getUpperBound - Looks through all the bounds info and
/// computes the upper bound given the current direction settings
/// at each level.
const SCEV *getUpperBound(BoundInfo *Bound) const;
/// exploreDirections - Hierarchically expands the direction vector
/// search space, combining the directions of discovered dependences
/// in the DirSet field of Bound. Returns the number of distinct
/// dependences discovered. If the dependence is disproved,
/// it will return 0.
unsigned exploreDirections(unsigned Level,
CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
const SmallBitVector &Loops,
unsigned &DepthExpanded,
const SCEV *Delta) const;
/// testBounds - Returns true iff the current bounds are plausible.
///
bool testBounds(unsigned char DirKind,
unsigned Level,
BoundInfo *Bound,
const SCEV *Delta) const;
/// findBoundsALL - Computes the upper and lower bounds for level K
/// using the * direction. Records them in Bound.
void findBoundsALL(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsLT - Computes the upper and lower bounds for level K
/// using the < direction. Records them in Bound.
void findBoundsLT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsGT - Computes the upper and lower bounds for level K
/// using the > direction. Records them in Bound.
void findBoundsGT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsEQ - Computes the upper and lower bounds for level K
/// using the = direction. Records them in Bound.
void findBoundsEQ(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// intersectConstraints - Updates X with the intersection
/// of the Constraints X and Y. Returns true if X has changed.
bool intersectConstraints(Constraint *X,
const Constraint *Y);
/// propagate - Review the constraints, looking for opportunities
/// to simplify a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagate(const SCEV *&Src,
const SCEV *&Dst,
SmallBitVector &Loops,
SmallVector<Constraint, 4> &Constraints,
bool &Consistent);
/// propagateDistance - Attempt to propagate a distance
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateDistance(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// propagatePoint - Attempt to propagate a point
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
bool propagatePoint(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint);
/// propagateLine - Attempt to propagate a line
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateLine(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// findCoefficient - Given a linear SCEV,
/// return the coefficient corresponding to specified loop.
/// If there isn't one, return the SCEV constant 0.
/// For example, given a*i + b*j + c*k, returning the coefficient
/// corresponding to the j loop would yield b.
const SCEV *findCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// zeroCoefficient - Given a linear SCEV,
/// return the SCEV given by zeroing out the coefficient
/// corresponding to the specified loop.
/// For example, given a*i + b*j + c*k, zeroing the coefficient
/// corresponding to the j loop would yield a*i + c*k.
const SCEV *zeroCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// addToCoefficient - Given a linear SCEV Expr,
/// return the SCEV given by adding some Value to the
/// coefficient corresponding to the specified TargetLoop.
/// For example, given a*i + b*j + c*k, adding 1 to the coefficient
/// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
const SCEV *addToCoefficient(const SCEV *Expr,
const Loop *TargetLoop,
const SCEV *Value) const;
/// updateDirection - Update direction vector entry
/// based on the current constraint.
void updateDirection(Dependence::DVEntry &Level,
const Constraint &CurConstraint) const;
public:
static char ID; // Class identification, replacement for typeinfo
DependenceAnalysis() : FunctionPass(ID) {
initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F);
void releaseMemory();
void getAnalysisUsage(AnalysisUsage &) const;
void print(raw_ostream &, const Module * = 0) const;
}; // class DependenceAnalysis
/// createDependenceAnalysisPass - This creates an instance of the
/// DependenceAnalysis pass.
FunctionPass *createDependenceAnalysisPass();
} // namespace llvm
#endif

View File

@ -346,7 +346,7 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
/// properlyDominates - Returns true iff this dominates N and this != N.
/// properlyDominates - Returns true iff A dominates B and A != B.
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,

View File

@ -28,7 +28,7 @@ class IVUsers;
class ScalarEvolution;
class SCEV;
class IVUsers;
class TargetData;
class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
@ -123,7 +123,7 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
TargetData *TD;
DataLayout *TD;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions

View File

@ -26,7 +26,7 @@
namespace llvm {
class CallSite;
class TargetData;
class DataLayout;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
@ -36,6 +36,9 @@ namespace llvm {
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
}
/// \brief Represents the cost of inlining a function.
@ -101,13 +104,13 @@ namespace llvm {
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
// TargetData if available, or null.
const TargetData *TD;
// DataLayout if available, or null.
const DataLayout *TD;
public:
InlineCostAnalyzer(): TD(0) {}
void setTargetData(const TargetData *TData) { TD = TData; }
void setDataLayout(const DataLayout *TData) { TD = TData; }
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.

View File

@ -24,7 +24,7 @@ namespace llvm {
class ArrayRef;
class DominatorTree;
class Instruction;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@ -32,122 +32,122 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -155,13 +155,13 @@ namespace llvm {
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -171,20 +171,20 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -198,7 +198,7 @@ namespace llvm {
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -209,7 +209,7 @@ namespace llvm {
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm

View File

@ -33,8 +33,8 @@ namespace llvm {
//
// IntervalPartition - This class builds and holds an "interval partition" for
// a function. This partition divides the control flow graph into a set of
// maximal intervals, as defined with the properties above. Intuitively, a
// BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
// maximal intervals, as defined with the properties above. Intuitively, an
// interval is a (possibly nonexistent) loop with a "tail" of non looping
// nodes following it.
//
class IntervalPartition : public FunctionPass {

View File

@ -19,18 +19,18 @@
namespace llvm {
class Constant;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
class TargetData *TD;
class DataLayout *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&); // DO NOT IMPLEMENT.
void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
void operator=(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
public:
static char ID;
LazyValueInfo() : FunctionPass(ID), PImpl(0) {

View File

@ -19,7 +19,7 @@
namespace llvm {
class AliasAnalysis;
class TargetData;
class DataLayout;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
@ -27,7 +27,7 @@ class MDNode;
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
unsigned Align, const TargetData *TD = 0);
unsigned Align, const DataLayout *TD = 0);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at

View File

@ -1,124 +0,0 @@
//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory
// accesses in loops.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// TODO: adapt as interface progresses
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class AliasAnalysis;
class AnalysisUsage;
class ScalarEvolution;
class SCEV;
class Value;
class raw_ostream;
class LoopDependenceAnalysis : public LoopPass {
AliasAnalysis *AA;
ScalarEvolution *SE;
/// L - The loop we are currently analysing.
Loop *L;
/// TODO: doc
enum DependenceResult { Independent = 0, Dependent = 1, Unknown = 2 };
/// TODO: doc
struct Subscript {
/// TODO: Add distance, direction, breaking conditions, ...
};
/// DependencePair - Represents a data dependence relation between to memory
/// reference instructions.
struct DependencePair : public FastFoldingSetNode {
Value *A;
Value *B;
DependenceResult Result;
SmallVector<Subscript, 4> Subscripts;
DependencePair(const FoldingSetNodeID &ID, Value *a, Value *b) :
FastFoldingSetNode(ID), A(a), B(b), Result(Unknown), Subscripts() {}
};
/// findOrInsertDependencePair - Return true if a DependencePair for the
/// given Values already exists, false if a new DependencePair had to be
/// created. The third argument is set to the pair found or created.
bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
/// getLoops - Collect all loops of the loop nest L in which
/// a given SCEV is variant.
void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
/// isLoopInvariant - True if a given SCEV is invariant in all loops of the
/// loop nest starting at the innermost loop L.
bool isLoopInvariant(const SCEV*) const;
/// isAffine - An SCEV is affine with respect to the loop nest starting at
/// the innermost loop L if it is of the form A+B*X where A, B are invariant
/// in the loop nest and X is a induction variable in the loop nest.
bool isAffine(const SCEV*) const;
/// TODO: doc
bool isZIVPair(const SCEV*, const SCEV*) const;
bool isSIVPair(const SCEV*, const SCEV*) const;
DependenceResult analyseZIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseMIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analysePair(DependencePair*) const;
public:
static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(ID) {
initializeLoopDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
/// isDependencePair - Check whether two values can possibly give rise to
/// a data dependence: that is the case if both are instructions accessing
/// memory and at least one of those accesses is a write.
bool isDependencePair(const Value*, const Value*) const;
/// depends - Return a boolean indicating if there is a data dependence
/// between two instructions.
bool depends(Value*, Value*);
bool runOnLoop(Loop*, LPPassManager&);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage&) const;
void print(raw_ostream&, const Module* = 0) const;
private:
FoldingSet<DependencePair> Pairs;
BumpPtrAllocator PairAllocator;
}; // class LoopDependenceAnalysis
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
} // namespace llvm
#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */

View File

@ -72,10 +72,9 @@ class LoopBase {
// Blocks - The list of blocks in this loop. First entry is the header node.
std::vector<BlockT*> Blocks;
// DO NOT IMPLEMENT
LoopBase(const LoopBase<BlockT, LoopT> &);
// DO NOT IMPLEMENT
const LoopBase<BlockT, LoopT>&operator=(const LoopBase<BlockT, LoopT> &);
LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
const LoopBase<BlockT, LoopT>&
operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
public:
/// Loop ctor - This creates an empty loop.
LoopBase() : ParentLoop(0) {}
@ -416,8 +415,8 @@ class LoopInfoBase {
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
void operator=(const LoopInfoBase &); // do not implement
LoopInfoBase(const LoopInfo &); // do not implement
void operator=(const LoopInfoBase &) LLVM_DELETED_FUNCTION;
LoopInfoBase(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
LoopInfoBase() { }
~LoopInfoBase() { releaseMemory(); }
@ -550,8 +549,8 @@ class LoopInfo : public FunctionPass {
LoopInfoBase<BasicBlock, Loop> LI;
friend class LoopBase<BasicBlock, Loop>;
void operator=(const LoopInfo &); // do not implement
LoopInfo(const LoopInfo &); // do not implement
void operator=(const LoopInfo &) LLVM_DELETED_FUNCTION;
LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid

View File

@ -145,7 +145,6 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
// Loop over the predecessors of the header node...
BlockT *Header = getHeader();
typedef GraphTraits<BlockT*> BlockTraits;
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header),

View File

@ -27,7 +27,8 @@
namespace llvm {
class CallInst;
class PointerType;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@ -35,27 +36,33 @@ class Value;
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a function that returns a
/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates uninitialized memory (such as malloc).
bool isMallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates zero-filled memory (such as calloc).
bool isCallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates memory (either malloc, calloc, or strdup like).
bool isAllocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// reallocates memory (such as realloc).
bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
//===----------------------------------------------------------------------===//
@ -65,36 +72,39 @@ bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
const CallInst *extractMallocCall(const Value *I);
static inline CallInst *extractMallocCall(Value *I) {
return const_cast<CallInst*>(extractMallocCall((const Value*)I));
const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractMallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
}
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
const CallInst *isArrayMalloc(const Value *I, const TargetData *TD);
const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// getMallocType - Returns the PointerType resulting from the malloc call.
/// The PointerType depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
PointerType *getMallocType(const CallInst *CI);
PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
/// The Type depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
Type *getMallocAllocatedType(const CallInst *CI);
Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
Value *getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
@ -104,9 +114,10 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
/// extractCallocCall - Returns the corresponding CallInst if the instruction
/// is a calloc call.
const CallInst *extractCallocCall(const Value *I);
static inline CallInst *extractCallocCall(Value *I) {
return const_cast<CallInst*>(extractCallocCall((const Value*)I));
const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractCallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI));
}
@ -115,10 +126,10 @@ static inline CallInst *extractCallocCall(Value *I) {
//
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I);
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *isFreeCall(Value *I) {
return const_cast<CallInst*>(isFreeCall((const Value*)I));
static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
}
@ -130,8 +141,8 @@ static inline CallInst *isFreeCall(Value *I) {
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
bool RoundToAlign = false);
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
@ -142,10 +153,12 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
SmallPtrSet<Instruction *, 8> SeenInsts;
APInt align(APInt Size, uint64_t Align);
@ -154,8 +167,8 @@ class ObjectSizeOffsetVisitor
}
public:
ObjectSizeOffsetVisitor(const TargetData *TD, LLVMContext &Context,
bool RoundToAlign = false);
ObjectSizeOffsetVisitor(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
@ -200,10 +213,10 @@ class ObjectSizeOffsetEvaluator
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
ObjectSizeOffsetVisitor Visitor;
IntegerType *IntTy;
Value *Zero;
CacheMapTy CacheMap;
@ -215,7 +228,8 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType compute_(Value *V);
public:
ObjectSizeOffsetEvaluator(const TargetData *TD, LLVMContext &Context);
ObjectSizeOffsetEvaluator(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context);
SizeOffsetEvalType compute(Value *V);
bool knownSize(SizeOffsetEvalType SizeOffset) {

View File

@ -29,7 +29,7 @@ namespace llvm {
class Instruction;
class CallSite;
class AliasAnalysis;
class TargetData;
class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
@ -323,7 +323,7 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
TargetData *TD;
DataLayout *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
@ -412,7 +412,7 @@ namespace llvm {
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
const TargetData &TD);
const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,

View File

@ -19,7 +19,7 @@
namespace llvm {
class DominatorTree;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
@ -37,7 +37,7 @@ class PHITransAddr {
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
const TargetData *TD;
const DataLayout *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@ -45,7 +45,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);

View File

@ -101,6 +101,14 @@ namespace llvm {
ModulePass *createProfileLoaderPass();
extern char &ProfileLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createProfileMetadataLoaderPass - This pass loads information from a
// profile dump file and sets branch weight metadata.
//
ModulePass *createProfileMetadataLoaderPass();
extern char &ProfileMetadataLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createNoProfileInfoPass - This pass implements the default "no profile".
@ -172,11 +180,20 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
// createDependenceAnalysisPass - This creates an instance of the
// DependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
FunctionPass *createDependenceAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createCostModelAnalysisPass - This creates an instance of the
// CostModelAnalysis pass.
//
FunctionPass *createCostModelAnalysisPass();
//===--------------------------------------------------------------------===//
//
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();

View File

@ -0,0 +1,139 @@
//===- ProfileDataLoader.h - Load & convert profile info ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The ProfileDataLoader class is used to load profiling data from a dump file.
// The ProfileDataT<FType, BType> class is used to store the mapping of this
// data to control flow edges.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
class ModulePass;
class Function;
class BasicBlock;
// Helper for dumping edges to dbgs().
raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *,
const BasicBlock *> E);
/// \brief The ProfileDataT<FType, BType> class is used to store the mapping of
/// profiling data to control flow edges.
///
/// An edge is defined by its source and sink basic blocks.
template<class FType, class BType>
class ProfileDataT {
public:
// The profiling information defines an Edge by its source and sink basic
// blocks.
typedef std::pair<const BType*, const BType*> Edge;
private:
typedef DenseMap<Edge, unsigned> EdgeWeights;
/// \brief Count the number of times a transition between two blocks is
/// executed.
///
/// As a special case, we also hold an edge from the null BasicBlock to the
/// entry block to indicate how many times the function was entered.
DenseMap<const FType*, EdgeWeights> EdgeInformation;
public:
/// getFunction() - Returns the Function for an Edge.
static const FType *getFunction(Edge e) {
// e.first may be NULL
assert(((!e.first) || (e.first->getParent() == e.second->getParent()))
&& "A ProfileData::Edge can not be between two functions");
assert(e.second && "A ProfileData::Edge must have a real sink");
return e.second->getParent();
}
/// getEdge() - Creates an Edge between two BasicBlocks.
static Edge getEdge(const BType *Src, const BType *Dest) {
return Edge(Src, Dest);
}
/// getEdgeWeight - Return the number of times that a given edge was
/// executed.
unsigned getEdgeWeight(Edge e) const {
const FType *f = getFunction(e);
assert((EdgeInformation.find(f) != EdgeInformation.end())
&& "No profiling information for function");
EdgeWeights weights = EdgeInformation.find(f)->second;
assert((weights.find(e) != weights.end())
&& "No profiling information for edge");
return weights.find(e)->second;
}
/// addEdgeWeight - Add 'weight' to the already stored execution count for
/// this edge.
void addEdgeWeight(Edge e, unsigned weight) {
EdgeInformation[getFunction(e)][e] += weight;
}
};
typedef ProfileDataT<Function, BasicBlock> ProfileData;
//typedef ProfileDataT<MachineFunction, MachineBasicBlock> MachineProfileData;
/// The ProfileDataLoader class is used to load raw profiling data from the
/// dump file.
class ProfileDataLoader {
private:
/// The name of the file where the raw profiling data is stored.
const std::string &Filename;
/// A vector of the command line arguments used when the target program was
/// run to generate profiling data. One entry per program run.
SmallVector<std::string, 1> CommandLines;
/// The raw values for how many times each edge was traversed, values from
/// multiple program runs are accumulated.
SmallVector<unsigned, 32> EdgeCounts;
public:
/// ProfileDataLoader ctor - Read the specified profiling data file, exiting
/// the program if the file is invalid or broken.
ProfileDataLoader(const char *ToolName, const std::string &Filename);
/// A special value used to represent the weight of an edge which has not
/// been counted yet.
static const unsigned Uncounted;
/// getNumExecutions - Return the number of times the target program was run
/// to generate this profiling data.
unsigned getNumExecutions() const { return CommandLines.size(); }
/// getExecution - Return the command line parameters used to generate the
/// i'th set of profiling data.
const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
const std::string &getFileName() const { return Filename; }
/// getRawEdgeCounts - Return the raw profiling data, this is just a list of
/// numbers with no mappings to edges.
ArrayRef<unsigned> getRawEdgeCounts() const { return EdgeCounts; }
};
/// createProfileMetadataLoaderPass - This function returns a Pass that loads
/// the profiling information for the module from the specified filename.
ModulePass *createProfileMetadataLoaderPass(const std::string &Filename);
} // End llvm namespace
#endif

View File

@ -0,0 +1,39 @@
/*===-- ProfileDataTypes.h - Profiling info shared constants --------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
|*===----------------------------------------------------------------------===*|
|*
|* This file defines constants shared by the various different profiling
|* runtime libraries and the LLVM C++ profile metadata loader. It must be a
|* C header because, at present, the profiling runtimes are written in C.
|*
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_ANALYSIS_PROFILEDATATYPES_H
#define LLVM_ANALYSIS_PROFILEDATATYPES_H
/* Included by libprofile. */
#if defined(__cplusplus)
extern "C" {
#endif
/* TODO: Strip out unused entries once ProfileInfo etc has been removed. */
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
BlockInfo = 3, /* Block profiling information */
EdgeInfo = 4, /* Edge profiling information */
PathInfo = 5, /* Path profiling information */
BBTraceInfo = 6, /* Basic block trace information */
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
#if defined(__cplusplus)
}
#endif
#endif /* LLVM_ANALYSIS_PROFILEDATATYPES_H */

View File

@ -27,15 +27,7 @@ enum ProfilingStorageType {
ProfilingHash = 2
};
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
BlockInfo = 3, /* Block profiling information */
EdgeInfo = 4, /* Edge profiling information */
PathInfo = 5, /* Path profiling information */
BBTraceInfo = 6, /* Basic block trace information */
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
#include "llvm/Analysis/ProfileDataTypes.h"
/*
* The header for tables that map path numbers to path counters.

View File

@ -54,10 +54,8 @@ class FlatIt {};
/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
/// Region.
class RegionNode {
// DO NOT IMPLEMENT
RegionNode(const RegionNode &);
// DO NOT IMPLEMENT
const RegionNode &operator=(const RegionNode &);
RegionNode(const RegionNode &) LLVM_DELETED_FUNCTION;
const RegionNode &operator=(const RegionNode &) LLVM_DELETED_FUNCTION;
protected:
/// This is the entry basic block that starts this region node. If this is a
@ -203,10 +201,8 @@ inline Region* RegionNode::getNodeAs<Region>() const {
/// tree, the second one creates a graphical representation using graphviz.
class Region : public RegionNode {
friend class RegionInfo;
// DO NOT IMPLEMENT
Region(const Region &);
// DO NOT IMPLEMENT
const Region &operator=(const Region &);
Region(const Region &) LLVM_DELETED_FUNCTION;
const Region &operator=(const Region &) LLVM_DELETED_FUNCTION;
// Information necessary to manage this Region.
RegionInfo* RI;
@ -473,27 +469,6 @@ class Region : public RegionNode {
const_iterator end() const { return children.end(); }
//@}
/// @name BasicBlock Node Iterators
///
/// These iterators iterate over all BasicBlock RegionNodes that are
/// contained in this Region. The iterator also iterates over BasicBlock
/// RegionNodes that are elements of a subregion of this Region. It is
/// therefore called a flat iterator.
//@{
typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
GraphTraits<FlatIt<RegionNode*> > > block_node_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<FlatIt<const RegionNode*> > >
const_block_node_iterator;
block_node_iterator block_node_begin();
block_node_iterator block_node_end();
const_block_node_iterator block_node_begin() const;
const_block_node_iterator block_node_end() const;
//@}
/// @name BasicBlock Iterators
///
/// These iterators iterate over all BasicBlocks that are contained in this
@ -586,10 +561,8 @@ class RegionInfo : public FunctionPass {
typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
typedef SmallPtrSet<Region*, 4> RegionSet;
// DO NOT IMPLEMENT
RegionInfo(const RegionInfo &);
// DO NOT IMPLEMENT
const RegionInfo &operator=(const RegionInfo &);
RegionInfo(const RegionInfo &) LLVM_DELETED_FUNCTION;
const RegionInfo &operator=(const RegionInfo &) LLVM_DELETED_FUNCTION;
DominatorTree *DT;
PostDominatorTree *PDT;

View File

@ -40,7 +40,7 @@ namespace llvm {
class DominatorTree;
class Type;
class ScalarEvolution;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
@ -70,8 +70,8 @@ namespace llvm {
unsigned short SubclassData;
private:
SCEV(const SCEV &); // DO NOT IMPLEMENT
void operator=(const SCEV &); // DO NOT IMPLEMENT
SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
public:
/// NoWrapFlags are bitfield indices into SubclassData.
@ -162,7 +162,6 @@ namespace llvm {
SCEVCouldNotCompute();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
static bool classof(const SCEV *S);
};
@ -227,7 +226,7 @@ namespace llvm {
/// TD - The target data information for the target we are targeting.
///
TargetData *TD;
DataLayout *TD;
/// TLI - The target library information for the target we are targeting.
///
@ -874,6 +873,7 @@ namespace llvm {
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module* = 0) const;
virtual void verifyAnalysis() const;
private:
FoldingSet<SCEV> UniqueSCEVs;

View File

@ -46,7 +46,6 @@ namespace llvm {
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVConstant *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scConstant;
}
@ -68,7 +67,6 @@ namespace llvm {
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCastExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
@ -88,7 +86,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVTruncateExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate;
}
@ -106,7 +103,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scZeroExtend;
}
@ -124,7 +120,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSignExtend;
}
@ -166,7 +161,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVNAryExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@ -188,7 +182,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@ -223,7 +216,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
}
@ -242,7 +234,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVMulExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scMulExpr;
}
@ -274,7 +265,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUDivExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUDivExpr;
}
@ -358,7 +348,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddRecExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddRecExpr;
}
@ -380,7 +369,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
}
@ -402,7 +390,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUMaxExpr;
}
@ -449,7 +436,6 @@ namespace llvm {
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUnknown *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUnknown;
}

View File

@ -130,9 +130,9 @@ class SparseSolver {
/// PHI nodes retriggered.
typedef std::pair<BasicBlock*,BasicBlock*> Edge;
std::set<Edge> KnownFeasibleEdges;
SparseSolver(const SparseSolver&); // DO NOT IMPLEMENT
void operator=(const SparseSolver&); // DO NOT IMPLEMENT
SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
public:
explicit SparseSolver(AbstractLatticeFunction *Lattice)
: LatticeFunc(Lattice) {}

View File

@ -22,7 +22,7 @@ namespace llvm {
class Value;
class Instruction;
class APInt;
class TargetData;
class DataLayout;
class StringRef;
class MDNode;
@ -37,27 +37,27 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
/// isPowerOfTwo - Return true if the given value is known to have exactly one
/// bit set when defined. For vectors return true if every element is known to
/// be a power of two when defined. Supports values with integer or pointer
/// type and vectors of integers. If 'OrZero' is set then returns true if the
/// given value is either a power of two or zero.
bool isPowerOfTwo(Value *V, const TargetData *TD = 0, bool OrZero = false,
bool isPowerOfTwo(Value *V, const DataLayout *TD = 0, bool OrZero = false,
unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
bool isKnownNonZero(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0);
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
@ -69,7 +69,7 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
/// ComputeNumSignBits - Return the number of times the sign bit of the
@ -80,7 +80,7 @@ namespace llvm {
///
/// 'Op' must have a scalar integer type.
///
unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = 0,
unsigned Depth = 0);
/// ComputeMultiple - This function computes the integer multiple of Base that
@ -118,10 +118,10 @@ namespace llvm {
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
const TargetData &TD);
const DataLayout &TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
const TargetData &TD) {
const DataLayout &TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
@ -143,10 +143,10 @@ namespace llvm {
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
Value *GetUnderlyingObject(Value *V, const TargetData *TD = 0,
Value *GetUnderlyingObject(Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6);
static inline const Value *
GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
GetUnderlyingObject(const Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6) {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
@ -156,7 +156,7 @@ namespace llvm {
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
const TargetData *TD = 0,
const DataLayout *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
@ -182,7 +182,7 @@ namespace llvm {
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
const TargetData *TD = 0);
const DataLayout *TD = 0);
} // end namespace llvm

View File

@ -68,8 +68,8 @@ class Argument : public Value, public ilist_node<Argument> {
/// attribute on it in its containing function.
bool hasNoCaptureAttr() const;
/// hasSRetAttr - Return true if this argument has the sret attribute on it in
/// its containing function.
/// hasStructRetAttr - Return true if this argument has the sret attribute on
/// it in its containing function.
bool hasStructRetAttr() const;
/// addAttr - Add a Attribute to an argument
@ -81,7 +81,6 @@ class Argument : public Value, public ilist_node<Argument> {
/// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
static inline bool classof(const Argument *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}

View File

@ -21,268 +21,280 @@
#include <string>
namespace llvm {
class AttrBuilder;
class AttributesImpl;
class LLVMContext;
class Type;
namespace Attribute {
/// We use this proxy POD type to allow constructing Attributes constants
/// using initializer lists. Do not use this class directly.
struct AttrConst {
uint64_t v;
AttrConst operator | (const AttrConst Attrs) const {
AttrConst Res = {v | Attrs.v};
return Res;
}
AttrConst operator ~ () const {
AttrConst Res = {~v};
return Res;
}
};
} // namespace Attribute
/// Attributes - A bitset of attributes.
class Attributes {
public:
Attributes() : Bits(0) { }
explicit Attributes(uint64_t Val) : Bits(Val) { }
/*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
// This is a "safe bool() operator".
operator const void *() const { return Bits ? this : 0; }
bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
bool operator == (const Attributes &Attrs) const {
return Bits == Attrs.Bits;
}
bool operator != (const Attributes &Attrs) const {
return Bits != Attrs.Bits;
}
Attributes operator | (const Attributes &Attrs) const {
return Attributes(Bits | Attrs.Bits);
}
Attributes operator & (const Attributes &Attrs) const {
return Attributes(Bits & Attrs.Bits);
}
Attributes operator ^ (const Attributes &Attrs) const {
return Attributes(Bits ^ Attrs.Bits);
}
Attributes &operator |= (const Attributes &Attrs) {
Bits |= Attrs.Bits;
public:
/// Function parameters and results can have attributes to indicate how they
/// should be treated by optimizations and code generation. This enumeration
/// lists the attributes that can be associated with parameters, function
/// results or the function itself.
///
/// 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
/// function.
///
/// In a theoretical system that uses tables for profiling and sjlj for
/// exceptions, they would be fully independent. In a normal system that uses
/// tables for both, the semantics are:
///
/// nil = Needs an entry because an exception might pass by.
/// nounwind = No need for an entry
/// uwtable = Needs an entry because the ABI says so and because
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
enum AttrVal {
// IR-Level Attributes
None, ///< No attributes have been set
AddressSafety, ///< Address safety checking is on.
Alignment, ///< Alignment of parameter (5 bits)
///< stored as log2 of alignment with +1 bias
///< 0 means unaligned different from align 1
AlwaysInline, ///< inline=always
ByVal, ///< Pass structure by value
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
MinSize, ///< Function must be optimized for size first
Naked, ///< Naked function
Nest, ///< Nested function static chain
NoAlias, ///< Considered to not alias after call
NoCapture, ///< Function creates no aliases of pointer
NoImplicitFloat, ///< Disable implicit floating point insts
NoInline, ///< inline=never
NonLazyBind, ///< Function is called early and/or
///< often, so lazy binding isn't worthwhile
NoRedZone, ///< Disable redzone
NoReturn, ///< Mark the function as not returning
NoUnwind, ///< Function doesn't unwind stack
OptimizeForSize, ///< opt_size
ReadNone, ///< Function does not access memory
ReadOnly, ///< Function only reads from memory
ReturnsTwice, ///< Function can return twice
SExt, ///< Sign extended before/after call
StackAlignment, ///< Alignment of stack for function (3 bits)
///< stored as log2 of alignment with +1 bias 0
///< means unaligned (different from
///< alignstack={1))
StackProtect, ///< Stack protection.
StackProtectReq, ///< Stack protection required.
StructRet, ///< Hidden pointer to structure to return
UWTable, ///< Function must be in a unwind table
ZExt ///< Zero extended before/after call
};
private:
AttributesImpl *Attrs;
Attributes(AttributesImpl *A) : Attrs(A) {}
public:
Attributes() : Attrs(0) {}
Attributes(const Attributes &A) : Attrs(A.Attrs) {}
Attributes &operator=(const Attributes &A) {
Attrs = A.Attrs;
return *this;
}
Attributes &operator &= (const Attributes &Attrs) {
Bits &= Attrs.Bits;
return *this;
/// get - Return a uniquified Attributes object. This takes the uniquified
/// value from the Builder and wraps it in the Attributes class.
static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals);
static Attributes get(LLVMContext &Context, AttrBuilder &B);
/// @brief Return true if the attribute is present.
bool hasAttribute(AttrVal Val) const;
/// @brief Return true if attributes exist
bool hasAttributes() const;
/// @brief Return true if the attributes are a non-null intersection.
bool hasAttributes(const Attributes &A) const;
/// @brief Returns the alignment field of an attribute as a byte alignment
/// value.
unsigned getAlignment() const;
/// @brief Returns the stack alignment field of an attribute as a byte
/// alignment value.
unsigned getStackAlignment() const;
/// @brief Parameter attributes that do not apply to vararg call arguments.
bool hasIncompatibleWithVarArgsAttrs() const {
return hasAttribute(Attributes::StructRet);
}
Attributes operator ~ () const { return Attributes(~Bits); }
uint64_t Raw() const { return Bits; }
private:
// Currently, we need less than 64 bits.
/// @brief Attributes that only apply to function parameters.
bool hasParameterOnlyAttrs() const {
return hasAttribute(Attributes::ByVal) ||
hasAttribute(Attributes::Nest) ||
hasAttribute(Attributes::StructRet) ||
hasAttribute(Attributes::NoCapture);
}
/// @brief Attributes that may be applied to the function itself. These cannot
/// be used on return values or function parameters.
bool hasFunctionOnlyAttrs() const {
return hasAttribute(Attributes::NoReturn) ||
hasAttribute(Attributes::NoUnwind) ||
hasAttribute(Attributes::ReadNone) ||
hasAttribute(Attributes::ReadOnly) ||
hasAttribute(Attributes::NoInline) ||
hasAttribute(Attributes::AlwaysInline) ||
hasAttribute(Attributes::OptimizeForSize) ||
hasAttribute(Attributes::StackProtect) ||
hasAttribute(Attributes::StackProtectReq) ||
hasAttribute(Attributes::NoRedZone) ||
hasAttribute(Attributes::NoImplicitFloat) ||
hasAttribute(Attributes::Naked) ||
hasAttribute(Attributes::InlineHint) ||
hasAttribute(Attributes::StackAlignment) ||
hasAttribute(Attributes::UWTable) ||
hasAttribute(Attributes::NonLazyBind) ||
hasAttribute(Attributes::ReturnsTwice) ||
hasAttribute(Attributes::AddressSafety) ||
hasAttribute(Attributes::MinSize);
}
bool operator==(const Attributes &A) const {
return Attrs == A.Attrs;
}
bool operator!=(const Attributes &A) const {
return Attrs != A.Attrs;
}
uint64_t Raw() const;
/// @brief Which attributes cannot be applied to a type.
static Attributes typeIncompatible(Type *Ty);
/// encodeLLVMAttributesForBitcode - This returns an integer containing an
/// encoding of all the LLVM attributes found in the given attribute bitset.
/// Any change to this encoding is a breaking change to bitcode compatibility.
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs);
/// decodeLLVMAttributesForBitcode - This returns an attribute bitset
/// containing the LLVM attributes that have been decoded from the given
/// integer. This function must stay in sync with
/// 'encodeLLVMAttributesForBitcode'.
static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C,
uint64_t EncodedAttrs);
/// getAsString - The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out the
/// mnemonics for the assembly writer.
/// @brief Convert attribute bits to text
std::string getAsString() const;
};
//===----------------------------------------------------------------------===//
/// AttrBuilder - This class is used in conjunction with the Attributes::get
/// method to create an Attributes object. The object itself is uniquified. The
/// Builder's value, however, is not. So this can be used as a quick way to test
/// for equality, presence of attributes, etc.
class AttrBuilder {
uint64_t Bits;
public:
AttrBuilder() : Bits(0) {}
explicit AttrBuilder(uint64_t B) : Bits(B) {}
AttrBuilder(const Attributes &A) : Bits(A.Raw()) {}
AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {}
void clear() { Bits = 0; }
/// addAttribute - Add an attribute to the builder.
AttrBuilder &addAttribute(Attributes::AttrVal Val);
/// removeAttribute - Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attributes::AttrVal Val);
/// addAttribute - Add the attributes from A to the builder.
AttrBuilder &addAttributes(const Attributes &A);
/// removeAttribute - Remove the attributes from A from the builder.
AttrBuilder &removeAttributes(const Attributes &A);
/// hasAttribute - Return true if the builder has the specified attribute.
bool hasAttribute(Attributes::AttrVal A) const;
/// hasAttributes - Return true if the builder has IR-level attributes.
bool hasAttributes() const;
/// hasAttributes - Return true if the builder has any attribute that's in the
/// specified attribute.
bool hasAttributes(const Attributes &A) const;
/// hasAlignmentAttr - Return true if the builder has an alignment attribute.
bool hasAlignmentAttr() const;
/// getAlignment - Retrieve the alignment attribute, if it exists.
uint64_t getAlignment() const;
/// getStackAlignment - Retrieve the stack alignment attribute, if it exists.
uint64_t getStackAlignment() const;
/// addAlignmentAttr - This turns an int alignment (which must be a power of
/// 2) into the form used internally in Attributes.
AttrBuilder &addAlignmentAttr(unsigned Align);
/// addStackAlignmentAttr - This turns an int stack alignment (which must be a
/// power of 2) into the form used internally in Attributes.
AttrBuilder &addStackAlignmentAttr(unsigned Align);
/// addRawValue - Add the raw value to the internal representation.
/// N.B. This should be used ONLY for decoding LLVM bitcode!
AttrBuilder &addRawValue(uint64_t Val);
/// @brief Remove attributes that are used on functions only.
void removeFunctionOnlyAttrs() {
removeAttribute(Attributes::NoReturn)
.removeAttribute(Attributes::NoUnwind)
.removeAttribute(Attributes::ReadNone)
.removeAttribute(Attributes::ReadOnly)
.removeAttribute(Attributes::NoInline)
.removeAttribute(Attributes::AlwaysInline)
.removeAttribute(Attributes::OptimizeForSize)
.removeAttribute(Attributes::StackProtect)
.removeAttribute(Attributes::StackProtectReq)
.removeAttribute(Attributes::NoRedZone)
.removeAttribute(Attributes::NoImplicitFloat)
.removeAttribute(Attributes::Naked)
.removeAttribute(Attributes::InlineHint)
.removeAttribute(Attributes::StackAlignment)
.removeAttribute(Attributes::UWTable)
.removeAttribute(Attributes::NonLazyBind)
.removeAttribute(Attributes::ReturnsTwice)
.removeAttribute(Attributes::AddressSafety)
.removeAttribute(Attributes::MinSize);
}
uint64_t Raw() const { return Bits; }
bool operator==(const AttrBuilder &B) {
return Bits == B.Bits;
}
bool operator!=(const AttrBuilder &B) {
return Bits != B.Bits;
}
};
namespace Attribute {
//===----------------------------------------------------------------------===//
// AttributeWithIndex
//===----------------------------------------------------------------------===//
/// Function parameters and results can have attributes to indicate how they
/// should be treated by optimizations and code generation. This enumeration
/// lists the attributes that can be associated with parameters, function
/// results or the function itself.
/// @brief Function attributes.
// We declare AttrConst objects that will be used throughout the code
// and also raw uint64_t objects with _i suffix to be used below for other
// constant declarations. This is done to avoid static CTORs and at the same
// time to keep type-safety of Attributes.
#define DECLARE_LLVM_ATTRIBUTE(name, value) \
const uint64_t name##_i = value; \
const AttrConst name = {value};
DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call
DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call
DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning
DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register
DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return
DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack
DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call
DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value
DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain
DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory
DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory
DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never
DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always
DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size
DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection.
DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required.
DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits)
// stored as log2 of alignment with +1 bias
// 0 means unaligned different from align 1
DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer
DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone
DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point
/// instructions.
DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function
DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was
///desirable
DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for
///function (3 bits) stored as log2
///of alignment with +1 bias
///0 means unaligned (different from
///alignstack= {1))
DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice
DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind
///table
DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on.
DECLARE_LLVM_ATTRIBUTE(IANSDialect,1ULL<<33) ///< Inline asm non-standard dialect.
/// When not set, ATT dialect assumed.
/// When set implies the Intel dialect.
#undef DECLARE_LLVM_ATTRIBUTE
/// 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
/// function.
/// In a theoretical system that uses tables for profiling and sjlj for
/// exceptions, they would be fully independent. In a normal system that
/// uses tables for both, the semantics are:
/// nil = Needs an entry because an exception might pass by.
/// nounwind = No need for an entry
/// uwtable = Needs an entry because the ABI says so and because
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
/// @brief Attributes that only apply to function parameters.
const AttrConst ParameterOnly = {ByVal_i | Nest_i |
StructRet_i | NoCapture_i};
/// @brief Attributes that may be applied to the function itself. These cannot
/// be used on return values or function parameters.
const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
Naked_i | InlineHint_i | StackAlignment_i |
UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i |
IANSDialect_i};
/// @brief Parameter attributes that do not apply to vararg call arguments.
const AttrConst VarArgsIncompatible = {StructRet_i};
/// @brief Attributes that are mutually incompatible.
const AttrConst MutuallyIncompatible[5] = {
{ByVal_i | Nest_i | StructRet_i},
{ByVal_i | Nest_i | InReg_i },
{ZExt_i | SExt_i},
{ReadNone_i | ReadOnly_i},
{NoInline_i | AlwaysInline_i}
};
/// @brief Which attributes cannot be applied to a type.
Attributes typeIncompatible(Type *Ty);
/// This turns an int alignment (a power of 2, normally) into the
/// form used internally in Attributes.
inline Attributes constructAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x40000000 && "Alignment too large.");
return Attributes((Log2_32(i)+1) << 16);
}
/// This returns the alignment field of an attribute as a byte alignment value.
inline unsigned getAlignmentFromAttrs(Attributes A) {
Attributes Align = A & Attribute::Alignment;
if (!Align)
return 0;
return 1U << ((Align.Raw() >> 16) - 1);
}
/// This turns an int stack alignment (which must be a power of 2) into
/// the form used internally in Attributes.
inline Attributes constructStackAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x100 && "Alignment too large.");
return Attributes((Log2_32(i)+1) << 26);
}
/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
inline unsigned getStackAlignmentFromAttrs(Attributes A) {
Attributes StackAlign = A & Attribute::StackAlignment;
if (!StackAlign)
return 0;
return 1U << ((StackAlign.Raw() >> 26) - 1);
}
/// This returns an integer containing an encoding of all the
/// LLVM attributes found in the given attribute bitset. Any
/// change to this encoding is a breaking change to bitcode
/// compatibility.
inline uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
// FIXME: It doesn't make sense to store the alignment information as an
// expanded out value, we should store it as a log2 value. However, we can't
// just change that here without breaking bitcode compatibility. If this ever
// becomes a problem in practice, we should introduce new tag numbers in the
// bitcode file and have those tags use a more efficiently encoded alignment
// field.
// Store the alignment in the bitcode as a 16-bit raw value instead of a
// 5-bit log2 encoded value. Shift the bits above the alignment up by
// 11 bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
if (Attrs & Attribute::Alignment)
EncodedAttrs |= (1ull << 16) <<
(((Attrs & Attribute::Alignment).Raw()-1) >> 16);
EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
return EncodedAttrs;
}
/// This returns an attribute bitset containing the LLVM attributes
/// that have been decoded from the given integer. This function
/// must stay in sync with 'encodeLLVMAttributesForBitcode'.
inline Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16.
// We shift the bits above 31 down by 11 bits.
unsigned Alignment = (EncodedAttrs & (0xffffull << 16)) >> 16;
assert((!Alignment || isPowerOf2_32(Alignment)) &&
"Alignment must be a power of two.");
Attributes Attrs(EncodedAttrs & 0xffff);
if (Alignment)
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
return Attrs;
}
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
/// the mnemonics for the assembly writer.
/// @brief Convert attribute bits to text
std::string getAsString(Attributes Attrs);
} // end namespace Attribute
/// This is just a pair of values to associate a set of attributes
/// with an index.
/// AttributeWithIndex - This is just a pair of values to associate a set of
/// attributes with an index.
struct AttributeWithIndex {
Attributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
///< Index 0 is used for return value attributes.
///< Index ~0U is used for function attributes.
Attributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
///< Index 0 is used for return value attributes.
///< Index ~0U is used for function attributes.
static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
ArrayRef<Attributes::AttrVal> Attrs) {
return get(Idx, Attributes::get(C, Attrs));
}
static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
AttributeWithIndex P;
P.Index = Idx;
@ -300,31 +312,42 @@ class AttributeListImpl;
/// AttrListPtr - This class manages the ref count for the opaque
/// AttributeListImpl object and provides accessors for it.
class AttrListPtr {
/// AttrList - The attributes that we are managing. This can be null
/// to represent the empty attributes list.
public:
enum AttrIndex {
ReturnIndex = 0U,
FunctionIndex = ~0U
};
private:
/// @brief The attributes that we are managing. This can be null to represent
/// the empty attributes list.
AttributeListImpl *AttrList;
/// @brief The attributes for the specified index are returned. Attributes
/// for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {}
public:
AttrListPtr() : AttrList(0) {}
AttrListPtr(const AttrListPtr &P);
AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {}
const AttrListPtr &operator=(const AttrListPtr &RHS);
~AttrListPtr();
//===--------------------------------------------------------------------===//
// Attribute List Construction and Mutation
//===--------------------------------------------------------------------===//
/// get - Return a Attributes list with the specified parameters in it.
static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs);
static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
/// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this
/// returns the new list.
AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const;
AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
/// removeAttr - Remove the specified attribute at the specified index from
/// this attribute list. Since attribute lists are immutable, this
/// returns the new list.
AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const;
AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
//===--------------------------------------------------------------------===//
// Attribute List Accessors
@ -332,36 +355,38 @@ class AttrListPtr {
/// getParamAttributes - The attributes for the specified index are
/// returned.
Attributes getParamAttributes(unsigned Idx) const {
assert (Idx && Idx != ~0U && "Invalid parameter index!");
return getAttributes(Idx);
}
/// getRetAttributes - The attributes for the ret value are
/// returned.
Attributes getRetAttributes() const {
return getAttributes(0);
return getAttributes(ReturnIndex);
}
/// getFnAttributes - The function attributes are returned.
Attributes getFnAttributes() const {
return getAttributes(~0U);
return getAttributes(FunctionIndex);
}
/// paramHasAttr - Return true if the specified parameter index has the
/// specified attribute set.
bool paramHasAttr(unsigned Idx, Attributes Attr) const {
return getAttributes(Idx) & Attr;
return getAttributes(Idx).hasAttributes(Attr);
}
/// getParamAlignment - Return the alignment for the specified function
/// parameter.
unsigned getParamAlignment(unsigned Idx) const {
return Attribute::getAlignmentFromAttrs(getAttributes(Idx));
return getAttributes(Idx).getAlignment();
}
/// hasAttrSomewhere - Return true if the specified attribute is set for at
/// least one parameter or for the return value.
bool hasAttrSomewhere(Attributes Attr) const;
bool hasAttrSomewhere(Attributes::AttrVal Attr) const;
unsigned getNumAttrs() const;
Attributes &getAttributesAtIndex(unsigned i) const;
/// operator==/!= - Provide equality predicates.
bool operator==(const AttrListPtr &RHS) const
@ -369,8 +394,6 @@ class AttrListPtr {
bool operator!=(const AttrListPtr &RHS) const
{ return AttrList != RHS.AttrList; }
void dump() const;
//===--------------------------------------------------------------------===//
// Attribute List Introspection
//===--------------------------------------------------------------------===//
@ -400,13 +423,7 @@ class AttrListPtr {
/// holds a index number plus a set of attributes.
const AttributeWithIndex &getSlot(unsigned Slot) const;
private:
explicit AttrListPtr(AttributeListImpl *L);
/// getAttributes - The attributes for the specified index are
/// returned. Attributes for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
void dump() const;
};
} // End llvm namespace

View File

@ -79,8 +79,8 @@ class BasicBlock : public Value, // Basic blocks are data objects also
void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock, Function>;
BasicBlock(const BasicBlock &); // Do not implement
void operator=(const BasicBlock &); // Do not implement
BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
/// BasicBlock ctor - If the function parameter is specified, the basic block
/// is automatically inserted at either the end of the function (if
@ -213,7 +213,6 @@ class BasicBlock : public Value, // Basic blocks are data objects also
ValueSymbolTable *getValueSymbolTable();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BasicBlock *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::BasicBlockVal;
}

View File

@ -415,8 +415,8 @@ class Archive {
/// name will be truncated at 15 characters. If \p Compress is specified,
/// all archive members will be compressed before being written. If
/// \p PrintSymTab is true, the symbol table will be printed to std::cout.
/// @returns true if an error occurred, \p error set to error message
/// @returns false if the writing succeeded.
/// @returns true if an error occurred, \p error set to error message;
/// returns false if the writing succeeded.
/// @brief Write (possibly modified) archive contents to disk
bool writeToDisk(
bool CreateSymbolTable=false, ///< Create Symbol table
@ -480,8 +480,8 @@ class Archive {
/// Writes one ArchiveMember to an ofstream. If an error occurs, returns
/// false, otherwise true. If an error occurs and error is non-null then
/// it will be set to an error message.
/// @returns false Writing member succeeded
/// @returns true Writing member failed, \p error set to error message
/// @returns false if writing member succeeded,
/// returns true if writing member failed, \p error set to error message.
bool writeMember(
const ArchiveMember& member, ///< The member to be written
std::ofstream& ARFile, ///< The file to write member onto
@ -527,9 +527,9 @@ class Archive {
/// @name Hidden
/// @{
private:
Archive(); ///< Do not implement
Archive(const Archive&); ///< Do not implement
Archive& operator=(const Archive&); ///< Do not implement
Archive() LLVM_DELETED_FUNCTION;
Archive(const Archive&) LLVM_DELETED_FUNCTION;
Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
/// @}
};

View File

@ -47,9 +47,9 @@ class BitstreamReader {
/// block/record name information in the BlockInfo block. Only llvm-bcanalyzer
/// uses this.
bool IgnoreBlockInfoNames;
BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT
void operator=(const BitstreamReader&); // DO NOT IMPLEMENT
BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION;
void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION;
public:
BitstreamReader() : IgnoreBlockInfoNames(true) {
}
@ -409,7 +409,7 @@ class BitstreamCursor {
}
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block is valid.
/// the block, and return true if the block has an error.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
// Save the current block's state on BlockScope.
BlockScope.push_back(Block(CurCodeSize));

View File

@ -155,6 +155,7 @@ class BitstreamWriter {
}
void EmitVBR(uint32_t Val, unsigned NumBits) {
assert(NumBits <= 32 && "Too many bits to emit!");
uint32_t Threshold = 1U << (NumBits-1);
// Emit the bits with VBR encoding, NumBits-1 bits at a time.
@ -167,10 +168,11 @@ class BitstreamWriter {
}
void EmitVBR64(uint64_t Val, unsigned NumBits) {
assert(NumBits <= 32 && "Too many bits to emit!");
if ((uint32_t)Val == Val)
return EmitVBR((uint32_t)Val, NumBits);
uint64_t Threshold = 1U << (NumBits-1);
uint32_t Threshold = 1U << (NumBits-1);
// Emit the bits with VBR encoding, NumBits-1 bits at a time.
while (Val >= Threshold) {

View File

@ -161,11 +161,14 @@ namespace bitc {
CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval]
CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr]
CST_CODE_INLINEASM_OLD = 18, // INLINEASM: [sideeffect|alignstack,
// asmstr,conststr]
CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval]
CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands]
CST_CODE_BLOCKADDRESS = 21, // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
CST_CODE_DATA = 22 // DATA: [n x elements]
CST_CODE_DATA = 22, // DATA: [n x elements]
CST_CODE_INLINEASM = 23 // INLINEASM: [sideeffect|alignstack|
// asmdialect,asmstr,conststr]
};
/// CastOpcodes - These are values used in the bitcode files to encode which

View File

@ -94,7 +94,29 @@ namespace CallingConv {
/// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
/// routines (i.e. GCC's save_volatiles attribute).
MBLAZE_SVOL = 74
MBLAZE_SVOL = 74,
/// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
/// No lowering or expansion of arguments.
/// Structures are passed as a pointer to a struct with the byval attribute.
/// Functions can only call SPIR_FUNC and SPIR_KERNEL functions.
/// Functions can only have zero or one return values.
/// Variable arguments are not allowed, except for printf.
/// How arguments/return values are lowered are not specified.
/// Functions are only visible to the devices.
SPIR_FUNC = 75,
/// SPIR_KERNEL - Calling convention for SPIR kernel functions.
/// Inherits the restrictions of SPIR_FUNC, except
/// Cannot have non-void return values.
/// Cannot have variable arguments.
/// Can also be called by the host.
/// Is externally visible.
SPIR_KERNEL = 76,
/// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins
Intel_OCL_BI = 77
};
} // End CallingConv namespace

View File

@ -17,6 +17,7 @@
#define LLVM_CODEGEN_ASMPRINTER_H
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/InlineAsm.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@ -47,7 +48,7 @@ namespace llvm {
class DwarfException;
class Mangler;
class TargetLoweringObjectFile;
class TargetData;
class DataLayout;
class TargetMachine;
/// AsmPrinter - This class is intended to be used as a driving class for all
@ -130,8 +131,8 @@ namespace llvm {
/// getObjFileLowering - Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
/// getTargetData - Return information about data layout.
const TargetData &getTargetData() const;
/// getDataLayout - Return information about data layout.
const DataLayout &getDataLayout() const;
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
@ -460,7 +461,8 @@ namespace llvm {
mutable unsigned SetCounter;
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = 0) const;
void EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = 0,
InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
/// EmitInlineAsm - This method formats and emits the specified machine
/// instruction that is an inline asm.

View File

@ -17,6 +17,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/CallingConv.h"
@ -288,6 +289,7 @@ class CCState {
StackOffset = ((StackOffset + Align-1) & ~(Align-1));
unsigned Result = StackOffset;
StackOffset += Size;
MF.getFrameInfo()->ensureMaxAlignment(Align);
return Result;
}

View File

@ -0,0 +1,228 @@
//===-- CommandFlags.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 codegen-specific flags that are shared between different
// command line tools. The tools "llc" and "opt" both use this file to prevent
// flag duplication.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetMachine.h"
#include <string>
using namespace llvm;
cl::opt<std::string>
MArch("march", cl::desc("Architecture to generate code for (see --version)"));
cl::opt<std::string>
MCPU("mcpu",
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
cl::value_desc("cpu-name"),
cl::init(""));
cl::list<std::string>
MAttrs("mattr",
cl::CommaSeparated,
cl::desc("Target specific attributes (-mattr=help for details)"),
cl::value_desc("a1,+a2,-a3,..."));
cl::opt<Reloc::Model>
RelocModel("relocation-model",
cl::desc("Choose relocation model"),
cl::init(Reloc::Default),
cl::values(
clEnumValN(Reloc::Default, "default",
"Target default relocation model"),
clEnumValN(Reloc::Static, "static",
"Non-relocatable code"),
clEnumValN(Reloc::PIC_, "pic",
"Fully relocatable, position independent code"),
clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
"Relocatable external references, non-relocatable code"),
clEnumValEnd));
cl::opt<llvm::CodeModel::Model>
CMModel("code-model",
cl::desc("Choose code model"),
cl::init(CodeModel::Default),
cl::values(clEnumValN(CodeModel::Default, "default",
"Target default code model"),
clEnumValN(CodeModel::Small, "small",
"Small code model"),
clEnumValN(CodeModel::Kernel, "kernel",
"Kernel code model"),
clEnumValN(CodeModel::Medium, "medium",
"Medium code model"),
clEnumValN(CodeModel::Large, "large",
"Large code model"),
clEnumValEnd));
cl::opt<bool>
RelaxAll("mc-relax-all",
cl::desc("When used with filetype=obj, "
"relax all fixups in the emitted object file"));
cl::opt<TargetMachine::CodeGenFileType>
FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
cl::desc("Choose a file type (not all types are supported by all targets):"),
cl::values(
clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
"Emit an assembly ('.s') file"),
clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
"Emit a native object ('.o') file"),
clEnumValN(TargetMachine::CGFT_Null, "null",
"Emit nothing, for performance testing"),
clEnumValEnd));
cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
cl::desc("Do not use .loc entries"));
cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
cl::desc("Do not use .cfi_* directives"));
cl::opt<bool> EnableDwarfDirectory("enable-dwarf-directory", cl::Hidden,
cl::desc("Use .file directives with an explicit directory."));
cl::opt<bool>
DisableRedZone("disable-red-zone",
cl::desc("Do not emit code that uses the red zone."),
cl::init(false));
cl::opt<bool>
EnableFPMAD("enable-fp-mad",
cl::desc("Enable less precise MAD instructions to be generated"),
cl::init(false));
cl::opt<bool>
DisableFPElim("disable-fp-elim",
cl::desc("Disable frame pointer elimination optimization"),
cl::init(false));
cl::opt<bool>
DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
cl::init(false));
cl::opt<bool>
EnableUnsafeFPMath("enable-unsafe-fp-math",
cl::desc("Enable optimizations that may decrease FP precision"),
cl::init(false));
cl::opt<bool>
EnableNoInfsFPMath("enable-no-infs-fp-math",
cl::desc("Enable FP math optimizations that assume no +-Infs"),
cl::init(false));
cl::opt<bool>
EnableNoNaNsFPMath("enable-no-nans-fp-math",
cl::desc("Enable FP math optimizations that assume no NaNs"),
cl::init(false));
cl::opt<bool>
EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
cl::Hidden,
cl::desc("Force codegen to assume rounding mode can change dynamically"),
cl::init(false));
cl::opt<bool>
GenerateSoftFloatCalls("soft-float",
cl::desc("Generate software floating point library calls"),
cl::init(false));
cl::opt<llvm::FloatABI::ABIType>
FloatABIForCalls("float-abi",
cl::desc("Choose float ABI type"),
cl::init(FloatABI::Default),
cl::values(
clEnumValN(FloatABI::Default, "default",
"Target default float ABI type"),
clEnumValN(FloatABI::Soft, "soft",
"Soft float ABI (implied by -soft-float)"),
clEnumValN(FloatABI::Hard, "hard",
"Hard float ABI (uses FP registers)"),
clEnumValEnd));
cl::opt<llvm::FPOpFusion::FPOpFusionMode>
FuseFPOps("fp-contract",
cl::desc("Enable aggresive formation of fused FP ops"),
cl::init(FPOpFusion::Standard),
cl::values(
clEnumValN(FPOpFusion::Fast, "fast",
"Fuse FP ops whenever profitable"),
clEnumValN(FPOpFusion::Standard, "on",
"Only fuse 'blessed' FP ops."),
clEnumValN(FPOpFusion::Strict, "off",
"Only fuse FP ops when the result won't be effected."),
clEnumValEnd));
cl::opt<bool>
DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::desc("Don't place zero-initialized symbols into bss section"),
cl::init(false));
cl::opt<bool>
EnableGuaranteedTailCallOpt("tailcallopt",
cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
cl::init(false));
cl::opt<bool>
DisableTailCalls("disable-tail-calls",
cl::desc("Never emit tail calls"),
cl::init(false));
cl::opt<unsigned>
OverrideStackAlignment("stack-alignment",
cl::desc("Override default stack alignment"),
cl::init(0));
cl::opt<bool>
EnableRealignStack("realign-stack",
cl::desc("Realign stack if needed"),
cl::init(true));
cl::opt<std::string>
TrapFuncName("trap-func", cl::Hidden,
cl::desc("Emit a call to trap function rather than a trap instruction"),
cl::init(""));
cl::opt<bool>
EnablePIE("enable-pie",
cl::desc("Assume the creation of a position independent executable."),
cl::init(false));
cl::opt<bool>
SegmentedStacks("segmented-stacks",
cl::desc("Use segmented stacks if possible."),
cl::init(false));
cl::opt<bool>
UseInitArray("use-init-array",
cl::desc("Use .init_array instead of .ctors."),
cl::init(false));
cl::opt<std::string> StopAfter("stop-after",
cl::desc("Stop compilation after a specific pass"),
cl::value_desc("pass-name"),
cl::init(""));
cl::opt<std::string> StartAfter("start-after",
cl::desc("Resume compilation after a specific pass"),
cl::value_desc("pass-name"),
cl::init(""));
cl::opt<unsigned>
SSPBufferSize("stack-protector-buffer-size", cl::init(8),
cl::desc("Lower bound for a buffer to be considered for "
"stack protection"));
#endif

View File

@ -32,7 +32,7 @@ class MachineFunction;
class MachineInstr;
class MachineFrameInfo;
class MachineRegisterInfo;
class TargetData;
class DataLayout;
class TargetInstrInfo;
class TargetLibraryInfo;
class TargetLowering;
@ -54,7 +54,7 @@ class FastISel {
MachineConstantPool &MCP;
DebugLoc DL;
const TargetMachine &TM;
const TargetData &TD;
const DataLayout &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;

View File

@ -122,6 +122,11 @@ namespace llvm {
Roots.push_back(GCRoot(Num, Metadata));
}
/// removeStackRoot - Removes a root.
roots_iterator removeStackRoot(roots_iterator position) {
return Roots.erase(position);
}
/// addSafePoint - Notes the existence of a safe point. Num is the ID of the
/// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).

View File

@ -48,9 +48,10 @@ namespace llvm {
// May only be subclassed.
GCMetadataPrinter();
// Do not implement.
GCMetadataPrinter(const GCMetadataPrinter &);
GCMetadataPrinter &operator=(const GCMetadataPrinter &);
private:
GCMetadataPrinter(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
GCMetadataPrinter &
operator=(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
public:
GCStrategy &getStrategy() { return *S; }

View File

@ -637,6 +637,10 @@ namespace ISD {
ATOMIC_LOAD_UMIN,
ATOMIC_LOAD_UMAX,
/// This corresponds to the llvm.lifetime.* intrinsics. The first operand
/// is the chain and the second operand is the alloca pointer.
LIFETIME_START, LIFETIME_END,
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific pre-isel opcode values start here.
BUILTIN_OP_END

View File

@ -21,15 +21,15 @@
namespace llvm {
class CallInst;
class Module;
class TargetData;
class DataLayout;
class IntrinsicLowering {
const TargetData& TD;
const DataLayout& TD;
bool Warned;
public:
explicit IntrinsicLowering(const TargetData &td) :
explicit IntrinsicLowering(const DataLayout &td) :
TD(td), Warned(false) {}
/// AddPrototypes - This method, if called, causes all of the prototypes

View File

@ -29,6 +29,7 @@
#include <climits>
namespace llvm {
class CoalescerPair;
class LiveIntervals;
class MachineInstr;
class MachineRegisterInfo;
@ -113,9 +114,6 @@ namespace llvm {
void dump() const;
void print(raw_ostream &os) const;
private:
LiveRange(); // DO NOT IMPLEMENT
};
template <> struct isPodLike<LiveRange> { static const bool value = true; };
@ -275,11 +273,6 @@ namespace llvm {
void MergeValueInAsValue(const LiveInterval &RHS,
const VNInfo *RHSValNo, VNInfo *LHSValNo);
/// Copy - Copy the specified live interval. This copies all the fields
/// except for the register of the interval.
void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
VNInfo::Allocator &VNInfoAllocator);
bool empty() const { return ranges.empty(); }
/// beginIndex - Return the lowest numbered slot covered by interval.
@ -312,12 +305,6 @@ namespace llvm {
return r != end() && r->end == index;
}
/// killedInRange - Return true if the interval has kills in [Start,End).
/// Note that the kill point is considered the end of a live range, so it is
/// not contained in the live range. If a live range ends at End, it won't
/// be counted as a kill by this method.
bool killedInRange(SlotIndex Start, SlotIndex End) const;
/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
const LiveRange *getLiveRangeContaining(SlotIndex Idx) const {
@ -366,6 +353,14 @@ namespace llvm {
return overlapsFrom(other, other.begin());
}
/// overlaps - Return true if the two intervals have overlapping segments
/// that are not coalescable according to CP.
///
/// Overlapping segments where one interval is defined by a coalescable
/// copy are allowed.
bool overlaps(const LiveInterval &Other, const CoalescerPair &CP,
const SlotIndexes&) const;
/// overlaps - Return true if the live interval overlaps a range specified
/// by [Start, End).
bool overlaps(SlotIndex Start, SlotIndex End) const;
@ -469,7 +464,7 @@ namespace llvm {
VNInfo *LHSValNo = 0,
const VNInfo *RHSValNo = 0);
LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
};
@ -501,7 +496,9 @@ namespace llvm {
if (I == E)
return;
// Is this an instruction live-in segment?
if (SlotIndex::isEarlierInstr(I->start, Idx)) {
// If Idx is the start index of a basic block, include live-in segments
// that start at Idx.getBaseIndex().
if (I->start <= Idx.getBaseIndex()) {
EarlyVal = I->valno;
EndPoint = I->end;
// Move to the potentially live-out segment.
@ -510,6 +507,12 @@ namespace llvm {
if (++I == E)
return;
}
// Special case: A PHIDef value can have its def in the middle of a
// segment if the value happens to be live out of the layout
// predecessor.
// Such a value is not live-in.
if (EarlyVal->def == Idx.getBaseIndex())
EarlyVal = 0;
}
// I now points to the segment that may be live-through, or defined by
// this instr. Ignore segments starting after the current instr.

View File

@ -65,12 +65,6 @@ namespace llvm {
/// Live interval pointers for all the virtual registers.
IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
/// AllocatableRegs - A bit vector of allocatable registers.
BitVector AllocatableRegs;
/// ReservedRegs - A bit vector of reserved registers.
BitVector ReservedRegs;
/// RegMaskSlots - Sorted list of instructions with register mask operands.
/// Always use the 'r' slot, RegMasks are normal clobbers, not early
/// clobbers.
@ -123,18 +117,6 @@ namespace llvm {
return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
}
/// isAllocatable - is the physical register reg allocatable in the current
/// function?
bool isAllocatable(unsigned reg) const {
return AllocatableRegs.test(reg);
}
/// isReserved - is the physical register reg reserved in the current
/// function
bool isReserved(unsigned reg) const {
return ReservedRegs.test(reg);
}
// Interval creation.
LiveInterval &getOrCreateInterval(unsigned Reg) {
if (!hasInterval(Reg)) {
@ -165,6 +147,26 @@ namespace llvm {
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = 0);
/// extendToIndices - Extend the live range of LI to reach all points in
/// Indices. The points in the Indices array must be jointly dominated by
/// existing defs in LI. PHI-defs are added as needed to maintain SSA form.
///
/// If a SlotIndex in Indices is the end index of a basic block, LI will be
/// extended to be live out of the basic block.
///
/// See also LiveRangeCalc::extend().
void extendToIndices(LiveInterval *LI, ArrayRef<SlotIndex> Indices);
/// pruneValue - If an LI value is live at Kill, prune its live range by
/// removing any liveness reachable from Kill. Add live range end points to
/// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
/// value's live range.
///
/// Calling pruneValue() and extendToIndices() can be used to reconstruct
/// SSA form after adding defs to a virtual register.
void pruneValue(LiveInterval *LI, SlotIndex Kill,
SmallVectorImpl<SlotIndex> *EndPoints);
SlotIndexes *getSlotIndexes() const {
return Indexes;
}
@ -252,21 +254,26 @@ namespace llvm {
/// addKillFlags - Add kill flags to any instruction that kills a virtual
/// register.
void addKillFlags();
void addKillFlags(const VirtRegMap*);
/// handleMove - call this method to notify LiveIntervals that
/// instruction 'mi' has been moved within a basic block. This will update
/// the live intervals for all operands of mi. Moves between basic blocks
/// are not supported.
void handleMove(MachineInstr* MI);
///
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
void handleMove(MachineInstr* MI, bool UpdateFlags = false);
/// moveIntoBundle - Update intervals for operands of MI so that they
/// begin/end on the SlotIndex for BundleStart.
///
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
///
/// Requires MI and BundleStart to have SlotIndexes, and assumes
/// existing liveness is accurate. BundleStart should be the first
/// instruction in the Bundle.
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart);
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
bool UpdateFlags = false);
// Register mask functions.
//

View File

@ -126,12 +126,6 @@ class LiveVariables : public MachineFunctionPass {
/// building live intervals.
SparseBitVector<> PHIJoins;
/// ReservedRegisters - This vector keeps track of which registers
/// are reserved register which are not allocatable by the target machine.
/// We can not track liveness for values that are in this set.
///
BitVector ReservedRegisters;
private: // Intermediate data structures
MachineFunction *MF;

View File

@ -351,6 +351,8 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
/// parameter is stored in Weights list and it may be used by
/// MachineBranchProbabilityInfo analysis to calculate branch probability.
///
/// Note that duplicate Machine CFG edges are not allowed.
///
void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
/// removeSuccessor - Remove successor from the successors list of this
@ -545,6 +547,28 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
return findDebugLoc(MBBI.getInstrIterator());
}
/// Possible outcome of a register liveness query to computeRegisterLiveness()
enum LivenessQueryResult {
LQR_Live, ///< Register is known to be live.
LQR_OverlappingLive, ///< Register itself is not live, but some overlapping
///< register is.
LQR_Dead, ///< Register is known to be dead.
LQR_Unknown ///< Register liveness not decidable from local
///< neighborhood.
};
/// computeRegisterLiveness - Return whether (physical) register \c Reg
/// has been <def>ined and not <kill>ed as of just before \c MI.
///
/// Search is localised to a neighborhood of
/// \c Neighborhood instructions before (searching for defs or kills) and
/// Neighborhood instructions after (searching just for defs) MI.
///
/// \c Reg must be a physical register.
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
unsigned Reg, MachineInstr *MI,
unsigned Neighborhood=10);
// Debugging methods.
void dump() const;
void print(raw_ostream &OS, SlotIndexes* = 0) const;
@ -572,7 +596,7 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
/// 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(const MachineBasicBlock *succ) const;
uint32_t getSuccWeight(const_succ_iterator Succ) const;
// Methods used to maintain doubly linked list of blocks...

View File

@ -16,14 +16,12 @@
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/BranchProbability.h"
#include <climits>
namespace llvm {
class raw_ostream;
class MachineBasicBlock;
class MachineBranchProbabilityInfo : public ImmutablePass {
virtual void anchor();
@ -52,6 +50,11 @@ class MachineBranchProbabilityInfo : public ImmutablePass {
uint32_t getEdgeWeight(const MachineBasicBlock *Src,
const MachineBasicBlock *Dst) const;
// Same thing, but using a const_succ_iterator from Src. This is faster when
// the iterator is already available.
uint32_t getEdgeWeight(const MachineBasicBlock *Src,
MachineBasicBlock::const_succ_iterator Dst) const;
// Get sum of the block successors' weights, potentially scaling them to fit
// within 32-bits. If scaling is required, sets Scale based on the necessary
// adjustment. Any edge weights used with the sum should be divided by Scale.

View File

@ -25,7 +25,7 @@ namespace llvm {
class Constant;
class FoldingSetNodeID;
class TargetData;
class DataLayout;
class TargetMachine;
class Type;
class MachineConstantPool;
@ -132,14 +132,14 @@ class MachineConstantPoolEntry {
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
const TargetData *TD; ///< The machine's TargetData.
const DataLayout *TD; ///< The machine's DataLayout.
unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
public:
/// @brief The only constructor.
explicit MachineConstantPool(const TargetData *td)
explicit MachineConstantPool(const DataLayout *td)
: TD(td), PoolAlignment(1) {}
~MachineConstantPool();

View File

@ -21,13 +21,15 @@
namespace llvm {
class raw_ostream;
class TargetData;
class DataLayout;
class TargetRegisterClass;
class Type;
class MachineFunction;
class MachineBasicBlock;
class TargetFrameLowering;
class BitVector;
class Value;
class AllocaInst;
/// The CalleeSavedInfo class tracks the information need to locate where a
/// callee saved register is in the current frame.
@ -103,14 +105,18 @@ class MachineFrameInfo {
// protector.
bool MayNeedSP;
/// Alloca - If this stack object is originated from an Alloca instruction
/// this value saves the original IR allocation. Can be NULL.
const AllocaInst *Alloca;
// PreAllocated - If true, the object was mapped into the local frame
// block and doesn't need additional handling for allocation beyond that.
bool PreAllocated;
StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
bool isSS, bool NSP)
bool isSS, bool NSP, const AllocaInst *Val)
: SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
isSpillSlot(isSS), MayNeedSP(NSP), PreAllocated(false) {}
isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
};
/// Objects - The list of stack objects allocated...
@ -362,6 +368,14 @@ class MachineFrameInfo {
ensureMaxAlignment(Align);
}
/// getObjectAllocation - Return the underlying Alloca of the specified
/// stack object if it exists. Returns 0 if none exists.
const AllocaInst* getObjectAllocation(int ObjectIdx) const {
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
return Objects[ObjectIdx+NumFixedObjects].Alloca;
}
/// NeedsStackProtector - Returns true if the object may need stack
/// protectors.
bool MayNeedStackProtector(int ObjectIdx) const {
@ -482,9 +496,10 @@ class MachineFrameInfo {
/// a nonnegative identifier to represent it.
///
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
bool MayNeedSP = false) {
bool MayNeedSP = false, const AllocaInst *Alloca = 0) {
assert(Size != 0 && "Cannot allocate zero size stack objects!");
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP,
Alloca));
int Index = (int)Objects.size() - NumFixedObjects - 1;
assert(Index >= 0 && "Bad frame index!");
ensureMaxAlignment(Alignment);
@ -516,7 +531,7 @@ class MachineFrameInfo {
///
int CreateVariableSizedObject(unsigned Alignment) {
HasVarSizedObjects = true;
Objects.push_back(StackObject(0, Alignment, 0, false, false, true));
Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
ensureMaxAlignment(Alignment);
return (int)Objects.size()-NumFixedObjects-1;
}

View File

@ -127,8 +127,8 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
void operator=(const MachineFunction&); // DO NOT IMPLEMENT
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
public:
MachineFunction(const Function *Fn, const TargetMachine &TM,
unsigned FunctionNum, MachineModuleInfo &MMI,
@ -138,15 +138,19 @@ class MachineFunction {
MachineModuleInfo &getMMI() const { return MMI; }
GCModuleInfo *getGMI() const { return GMI; }
MCContext &getContext() const { return Ctx; }
/// getFunction - Return the LLVM function that this machine code represents
///
const Function *getFunction() const { return Fn; }
/// getName - Return the name of the corresponding LLVM function.
///
StringRef getName() const;
/// getFunctionNumber - Return a unique ID for the current function.
///
unsigned getFunctionNumber() const { return FunctionNumber; }
/// getTarget - Return the target machine this machine code is compiled with
///
const TargetMachine &getTarget() const { return Target; }

View File

@ -25,6 +25,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/InlineAsm.h"
#include "llvm/Support/DebugLoc.h"
#include <vector>
@ -81,8 +82,8 @@ class MachineInstr : public ilist_node<MachineInstr> {
MachineBasicBlock *Parent; // Pointer to the owning basic block.
DebugLoc debugLoc; // Source line information.
MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT
void operator=(const MachineInstr&); // DO NOT IMPLEMENT
MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION;
void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION;
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
@ -97,25 +98,10 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// MCID NULL and no operands.
MachineInstr();
// The next two constructors have DebugLoc and non-DebugLoc versions;
// over time, the non-DebugLoc versions should be phased out and eventually
// removed.
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified
/// 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 MCInstrDesc &MCID);
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
/// MCInstrDesc. An explicit DebugLoc is supplied.
explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
bool NoImp = false);
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
@ -459,6 +445,11 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
bool mayLoad(QueryType Type = AnyInBundle) const {
if (isInlineAsm()) {
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
if (ExtraInfo & InlineAsm::Extra_MayLoad)
return true;
}
return hasProperty(MCID::MayLoad, Type);
}
@ -468,6 +459,11 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
bool mayStore(QueryType Type = AnyInBundle) const {
if (isInlineAsm()) {
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
if (ExtraInfo & InlineAsm::Extra_MayStore)
return true;
}
return hasProperty(MCID::MayStore, Type);
}
@ -610,6 +606,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
bool isStackAligningInlineAsm() const;
InlineAsm::AsmDialect getInlineAsmDialect() const;
bool isInsertSubreg() const {
return getOpcode() == TargetOpcode::INSERT_SUBREG;
}
@ -782,16 +779,43 @@ class MachineInstr : public ilist_node<MachineInstr> {
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI) const;
/// tieOperands - Add a tie between the register operands at DefIdx and
/// UseIdx. The tie will cause the register allocator to ensure that the two
/// operands are assigned the same physical register.
///
/// Tied operands are managed automatically for explicit operands in the
/// MCInstrDesc. This method is for exceptional cases like inline asm.
void tieOperands(unsigned DefIdx, unsigned UseIdx);
/// findTiedOperandIdx - Given the index of a tied register operand, find the
/// operand it is tied to. Defs are tied to uses and vice versa. Returns the
/// index of the tied operand which must exist.
unsigned findTiedOperandIdx(unsigned OpIdx) const;
/// isRegTiedToUseOperand - Given the index of a register def operand,
/// check if the register def is tied to a source operand, due to either
/// two-address elimination or inline assembly constraints. Returns the
/// first tied use operand index by reference if UseOpIdx is not null.
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const;
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const {
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || !MO.isTied())
return false;
if (UseOpIdx)
*UseOpIdx = findTiedOperandIdx(DefOpIdx);
return true;
}
/// isRegTiedToDefOperand - Return true if the use operand of the specified
/// index is tied to an def operand. It also returns the def operand index by
/// reference if DefOpIdx is not null.
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const;
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const {
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || !MO.isTied())
return false;
if (DefOpIdx)
*DefOpIdx = findTiedOperandIdx(UseOpIdx);
return true;
}
/// clearKillInfo - Clears kill flags on all operands.
///
@ -852,11 +876,11 @@ class MachineInstr : public ilist_node<MachineInstr> {
bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA,
unsigned DstReg) const;
/// hasVolatileMemoryRef - Return true if this instruction may have a
/// volatile memory reference, or if the information describing the
/// memory reference is not available. Return false if it is known to
/// have no volatile memory references.
bool hasVolatileMemoryRef() const;
/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no
/// ordered or volatile memory references.
bool hasOrderedMemoryRef() const;
/// isInvariantLoad - Return true if this instruction is loading from a
/// location whose value is invariant across the function. For example,
@ -935,6 +959,15 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// return null.
MachineRegisterInfo *getRegInfo();
/// untieRegOperand - Break any tie involving OpIdx.
void untieRegOperand(unsigned OpIdx) {
MachineOperand &MO = getOperand(OpIdx);
if (MO.isReg() && MO.isTied()) {
getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0;
MO.TiedTo = 0;
}
}
/// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction.
void addImplicitDefUseOperands();

View File

@ -176,15 +176,24 @@ class MachineInstrBuilder {
}
// Add a displacement from an existing MachineOperand with an added offset.
const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
int64_t off) const {
const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off,
unsigned char TargetFlags = 0) const {
switch (Disp.getType()) {
default:
llvm_unreachable("Unhandled operand type in addDisp()");
case MachineOperand::MO_Immediate:
return addImm(Disp.getImm() + off);
case MachineOperand::MO_GlobalAddress:
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
case MachineOperand::MO_GlobalAddress: {
// If caller specifies new TargetFlags then use it, otherwise the
// default behavior is to copy the target flags from the existing
// MachineOperand. This means if the caller wants to clear the
// target flags it needs to do so explicitly.
if (TargetFlags)
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
TargetFlags);
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
Disp.getTargetFlags());
}
}
}
};

View File

@ -130,9 +130,9 @@ class MachineOperandIteratorBase {
return OpI - InstrI->operands_begin();
}
/// RegInfo - Information about a virtual register used by a set of operands.
/// VirtRegInfo - Information about a virtual register used by a set of operands.
///
struct RegInfo {
struct VirtRegInfo {
/// Reads - One of the operands read the virtual register. This does not
/// include <undef> or <internal> use operands, see MO::readsReg().
bool Reads;
@ -146,6 +146,32 @@ class MachineOperandIteratorBase {
bool Tied;
};
/// PhysRegInfo - Information about a physical register used by a set of
/// operands.
struct PhysRegInfo {
/// Clobbers - Reg or an overlapping register is defined, or a regmask
/// clobbers Reg.
bool Clobbers;
/// Defines - Reg or a super-register is defined.
bool Defines;
/// DefinesOverlap - Reg or an overlapping register is defined.
bool DefinesOverlap;
/// Reads - Read or a super-register is read.
bool Reads;
/// ReadsOverlap - Reg or an overlapping register is read.
bool ReadsOverlap;
/// DefinesDead - All defs of a Reg or a super-register are dead.
bool DefinesDead;
/// There is a kill of Reg or a super-register.
bool Kills;
};
/// analyzeVirtReg - Analyze how the current instruction or bundle uses a
/// virtual register. This function should not be called after operator++(),
/// it expects a fresh iterator.
@ -154,8 +180,16 @@ class MachineOperandIteratorBase {
/// @param Ops When set, this vector will receive an (MI, OpNum) entry for
/// each operand referring to Reg.
/// @returns A filled-in RegInfo struct.
RegInfo analyzeVirtReg(unsigned Reg,
VirtRegInfo analyzeVirtReg(unsigned Reg,
SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = 0);
/// analyzePhysReg - Analyze how the current instruction or bundle uses a
/// physical register. This function should not be called after operator++(),
/// it expects a fresh iterator.
///
/// @param Reg The physical register to analyze.
/// @returns A filled-in PhysRegInfo struct.
PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI);
};
/// MIOperands - Iterate over operands of a single instruction.

View File

@ -26,7 +26,7 @@
namespace llvm {
class MachineBasicBlock;
class TargetData;
class DataLayout;
class raw_ostream;
/// MachineJumpTableEntry - One jump table in the jump table info.
@ -84,9 +84,9 @@ class MachineJumpTableInfo {
JTEntryKind getEntryKind() const { return EntryKind; }
/// getEntrySize - Return the size of each entry in the jump table.
unsigned getEntrySize(const TargetData &TD) const;
unsigned getEntrySize(const DataLayout &TD) const;
/// getEntryAlignment - Return the alignment of each entry in the jump table.
unsigned getEntryAlignment(const TargetData &TD) const;
unsigned getEntryAlignment(const DataLayout &TD) const;
/// createJumpTableIndex - Create a new jump table.
///

View File

@ -73,8 +73,8 @@ class MachineLoopInfo : public MachineFunctionPass {
LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
friend class LoopBase<MachineBasicBlock, MachineLoop>;
void operator=(const MachineLoopInfo &); // do not implement
MachineLoopInfo(const MachineLoopInfo &); // do not implement
void operator=(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
MachineLoopInfo(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid

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