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:
commit
3861d79fd7
contrib/llvm/include
llvm-c
llvm
ADT
APFloat.hAPInt.hArrayRef.hBitVector.hDAGDeltaAlgorithm.hDeltaAlgorithm.hDenseMap.hDenseMapInfo.hEquivalenceClasses.hFoldingSet.hHashing.hImmutableList.hImmutableMap.hImmutableSet.hMapVector.hOptional.hOwningPtr.hPackedVector.hPointerIntPair.hScopedHashTable.hSetVector.hSmallBitVector.hSmallPtrSet.hSmallString.hSmallVector.hSparseBitVector.hSparseSet.hStringExtras.hStringRef.hStringSet.hTrie.hTriple.hTwine.hValueMap.hilist.h
AddressingMode.hAnalysis
AliasAnalysis.hAliasSetTracker.hBranchProbabilityInfo.hCallGraph.hCaptureTracking.hCodeMetrics.hConstantFolding.hDependenceAnalysis.hDominators.hIVUsers.hInlineCost.hInstructionSimplify.hIntervalPartition.hLazyValueInfo.hLoads.hLoopDependenceAnalysis.hLoopInfo.hLoopInfoImpl.hMemoryBuiltins.hMemoryDependenceAnalysis.hPHITransAddr.hPasses.hProfileDataLoader.hProfileDataTypes.hProfileInfoTypes.hRegionInfo.hScalarEvolution.hScalarEvolutionExpressions.hSparsePropagation.hValueTracking.h
Argument.hAttributes.hBasicBlock.hBitcode
CallingConv.hCodeGen
AsmPrinter.hCallingConvLower.hCommandFlags.hFastISel.hGCMetadata.hGCMetadataPrinter.hISDOpcodes.hIntrinsicLowering.hLiveInterval.hLiveIntervalAnalysis.hLiveVariables.hMachineBasicBlock.hMachineBranchProbabilityInfo.hMachineConstantPool.hMachineFrameInfo.hMachineFunction.hMachineInstr.hMachineInstrBuilder.hMachineInstrBundle.hMachineJumpTableInfo.hMachineLoopInfo.h
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -36,6 +36,9 @@ extern "C" {
|
||||
/** See llvm::createBBVectorizePass function. */
|
||||
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createLoopVectorizePass function. */
|
||||
void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -251,7 +251,7 @@ public:
|
||||
/// 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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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
|
||||
|
@ -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.
|
||||
|
@ -172,7 +172,7 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ private:
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,17 +48,18 @@ public:
|
||||
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 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -45,23 +45,23 @@ private:
|
||||
/// 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 @@ protected:
|
||||
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);
|
||||
|
@ -420,9 +420,10 @@ private:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -278,6 +278,10 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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.
|
||||
|
@ -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 {
|
||||
|
@ -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; }
|
||||
|
@ -122,8 +122,8 @@ public:
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -84,13 +83,13 @@ public:
|
||||
}
|
||||
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 @@ private:
|
||||
/// 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 @@ private:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ protected:
|
||||
// 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 @@ protected:
|
||||
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 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
markImmutable(getLeft(T));
|
||||
markImmutable(getRight(T));
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
TreeTy *getCanonicalTree(TreeTy *TNew) {
|
||||
if (!TNew)
|
||||
@ -937,7 +936,7 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
~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 @@ public:
|
||||
//===--------------------------------------------------===//
|
||||
// Iterators.
|
||||
//===--------------------------------------------------===//
|
||||
|
||||
|
||||
class iterator {
|
||||
typename TreeTy::iterator itr;
|
||||
iterator(TreeTy* t) : itr(t) {}
|
||||
@ -1194,28 +1193,28 @@ public:
|
||||
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(); }
|
||||
};
|
||||
|
||||
|
90
contrib/llvm/include/llvm/ADT/MapVector.h
Normal file
90
contrib/llvm/include/llvm/ADT/MapVector.h
Normal 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
|
@ -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 @@ public:
|
||||
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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 @@ protected:
|
||||
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 @@ protected:
|
||||
/// @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 {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -300,6 +300,21 @@ public:
|
||||
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 @@ public:
|
||||
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());
|
||||
|
@ -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 @@ private:
|
||||
/// 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.
|
||||
|
@ -44,25 +44,25 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// @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 @@ public:
|
||||
}
|
||||
|
||||
|
||||
/// 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 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// @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...
|
||||
|
@ -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 @@ protected:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
#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 @@ public:
|
||||
|
||||
};
|
||||
|
||||
/// 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();
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
&& "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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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
|
@ -65,7 +65,9 @@ public:
|
||||
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 @@ public:
|
||||
PC,
|
||||
SCEI,
|
||||
BGP,
|
||||
BGQ
|
||||
BGQ,
|
||||
Freescale,
|
||||
IBM
|
||||
};
|
||||
enum OSType {
|
||||
UnknownOS,
|
||||
@ -99,7 +103,8 @@ public:
|
||||
RTEMS,
|
||||
NativeClient,
|
||||
CNK, // BG/P Compute-Node Kernel
|
||||
Bitrig
|
||||
Bitrig,
|
||||
AIX
|
||||
};
|
||||
enum EnvironmentType {
|
||||
UnknownEnvironment,
|
||||
@ -109,7 +114,8 @@ public:
|
||||
GNUEABIHF,
|
||||
EABI,
|
||||
MachO,
|
||||
ANDROIDEABI
|
||||
Android,
|
||||
ELF
|
||||
};
|
||||
|
||||
private:
|
||||
@ -341,7 +347,7 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// @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 @@ public:
|
||||
/// \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 @@ public:
|
||||
/// 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);
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/// @}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
41
contrib/llvm/include/llvm/AddressingMode.h
Normal file
41
contrib/llvm/include/llvm/AddressingMode.h
Normal 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
|
@ -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 @@ protected:
|
||||
|
||||
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 @@ public:
|
||||
/// 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 @@ public:
|
||||
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;
|
||||
|
@ -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 @@ private:
|
||||
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;
|
||||
|
@ -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 @@ public:
|
||||
/// (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 @@ public:
|
||||
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
|
||||
|
@ -185,9 +185,9 @@ private:
|
||||
/// 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:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
885
contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h
Normal file
885
contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h
Normal 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
|
@ -346,7 +346,7 @@ public:
|
||||
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,
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
139
contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h
Normal file
139
contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h
Normal 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
|
39
contrib/llvm/include/llvm/Analysis/ProfileDataTypes.h
Normal file
39
contrib/llvm/include/llvm/Analysis/ProfileDataTypes.h
Normal 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 */
|
@ -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.
|
||||
|
@ -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 @@ public:
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -68,8 +68,8 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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;
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
/// 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 @@ public:
|
||||
bool operator!=(const AttrListPtr &RHS) const
|
||||
{ return AttrList != RHS.AttrList; }
|
||||
|
||||
void dump() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Attribute List Introspection
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -400,13 +423,7 @@ public:
|
||||
/// 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
|
||||
|
@ -79,8 +79,8 @@ private:
|
||||
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 @@ public:
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
/// @}
|
||||
};
|
||||
|
||||
|
@ -47,9 +47,9 @@ private:
|
||||
/// 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 @@ public:
|
||||
}
|
||||
|
||||
/// 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));
|
||||
|
@ -155,6 +155,7 @@ public:
|
||||
}
|
||||
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 @@ public:
|
||||
StackOffset = ((StackOffset + Align-1) & ~(Align-1));
|
||||
unsigned Result = StackOffset;
|
||||
StackOffset += Size;
|
||||
MF.getFrameInfo()->ensureMaxAlignment(Align);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
228
contrib/llvm/include/llvm/CodeGen/CommandFlags.h
Normal file
228
contrib/llvm/include/llvm/CodeGen/CommandFlags.h
Normal 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
|
@ -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 @@ protected:
|
||||
MachineConstantPool &MCP;
|
||||
DebugLoc DL;
|
||||
const TargetMachine &TM;
|
||||
const TargetData &TD;
|
||||
const DataLayout &TD;
|
||||
const TargetInstrInfo &TII;
|
||||
const TargetLowering &TLI;
|
||||
const TargetRegisterInfo &TRI;
|
||||
|
@ -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).
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -126,12 +126,6 @@ private:
|
||||
/// 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;
|
||||
|
||||
|
@ -351,6 +351,8 @@ public:
|
||||
/// 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 @@ public:
|
||||
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 @@ private:
|
||||
/// 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...
|
||||
|
@ -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 @@ public:
|
||||
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.
|
||||
|
@ -25,7 +25,7 @@ namespace llvm {
|
||||
|
||||
class Constant;
|
||||
class FoldingSetNodeID;
|
||||
class TargetData;
|
||||
class DataLayout;
|
||||
class TargetMachine;
|
||||
class Type;
|
||||
class MachineConstantPool;
|
||||
@ -132,14 +132,14 @@ public:
|
||||
/// 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();
|
||||
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
/// 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 @@ public:
|
||||
///
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
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; }
|
||||
|
@ -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 @@ private:
|
||||
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 @@ private:
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ private:
|
||||
/// 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();
|
||||
|
@ -176,15 +176,24 @@ public:
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -130,9 +130,9 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
/// @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.
|
||||
|
@ -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 @@ public:
|
||||
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.
|
||||
///
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user