diff options
Diffstat (limited to 'include')
299 files changed, 8550 insertions, 3935 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 0bd5db3..620d088 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.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); @@ -1869,6 +1869,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 diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index 69fdc64..b8c4ad9 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -146,6 +146,15 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, 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. */ void LLVMDisasmDispose(LLVMDisasmContextRef DC); diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index 8915040..57abfa0 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -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) { diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h index 0d35d73..29668de 100644 --- a/include/llvm-c/TargetMachine.h +++ b/include/llvm-c/TargetMachine.h @@ -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 diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h index 9e7c754..68a9bdd 100644 --- a/include/llvm-c/Transforms/Vectorize.h +++ b/include/llvm-c/Transforms/Vectorize.h @@ -36,6 +36,9 @@ extern "C" { /** See llvm::createBBVectorizePass function. */ void LLVMAddBBVectorizePass(LLVMPassManagerRef PM); +/** See llvm::createLoopVectorizePass function. */ +void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM); + /** * @} */ diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 5a625a4..31c6e6a 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -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 */ diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index f30a6e3..c7c8016b 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.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 diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index cf55aad..1e35d62 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -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. diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 3e2e5f2..9d6388f 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -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; } } diff --git a/include/llvm/ADT/DAGDeltaAlgorithm.h b/include/llvm/ADT/DAGDeltaAlgorithm.h index e502ac4..2dfed07 100644 --- a/include/llvm/ADT/DAGDeltaAlgorithm.h +++ b/include/llvm/ADT/DAGDeltaAlgorithm.h @@ -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; }; diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h index 45ba198..7bf7960 100644 --- a/include/llvm/ADT/DeltaAlgorithm.h +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -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); diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index f60d688..ac4bdbd 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -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. diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 1559a35..6f17a64 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -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) { diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index 771476c..1d81772 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -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 diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index ba415ac..375d84a 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -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. diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 6ab0725..cda31a2 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -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 { diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index d7c0074..20bdd90 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -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; } diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index 8346ffa..4883c5b 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -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 { diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 949dc44..3900f96 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -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(); } }; diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h new file mode 100644 index 0000000..6aacca5 --- /dev/null +++ b/include/llvm/ADT/MapVector.h @@ -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 diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index ee8b69f..f43aeb1 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -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(); } diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h index 6d9c305..05bcd40 100644 --- a/include/llvm/ADT/OwningPtr.h +++ b/include/llvm/ADT/OwningPtr.h @@ -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; } diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h index 2eaddc2..1ae2a77 100644 --- a/include/llvm/ADT/PackedVector.h +++ b/include/llvm/ADT/PackedVector.h @@ -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 { diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index fcc758b..71c379b 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -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)); } diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index a6803ee..efddd9f 100644 --- a/include/llvm/ADT/ScopedHashTable.h +++ b/include/llvm/ADT/ScopedHashTable.h @@ -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(); diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index 965f0de..d2f7286 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -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; } - - /// @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 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; + } + + + /// \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); diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 7a645e0..a9cd54e 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -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()); diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 498a034..3bb8830 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -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. diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h index c6f0a5b..8da99d1 100644 --- a/include/llvm/ADT/SmallString.h +++ b/include/llvm/ADT/SmallString.h @@ -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... diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 9fbbbe4..6e0fd94 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -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,44 +33,20 @@ class SmallVectorBase { protected: void *BeginX, *EndX, *CapacityX; - // 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; - // 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) {} - - /// isSmall - Return true if this is a smallvector which has not had dynamic - /// memory allocated for it. - bool isSmall() const { - return BeginX == static_cast<const void*>(&FirstEl); - } - - /// resetToSmall - Put this vector in a state of being small. - void resetToSmall() { - BeginX = EndX = CapacityX = &FirstEl; - } + 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(size_t MinSizeInBytes, size_t TSize); + 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); @@ -78,11 +55,41 @@ public: bool empty() const { return BeginX == EndX; } }; +template <typename T, unsigned N> struct SmallVectorStorage; -template <typename T> +/// 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. 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: - SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(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. + bool isSmall() const { + return BeginX == static_cast<const void*>(&FirstEl); + } + + /// resetToSmall - Put this vector in a state of being small. + void resetToSmall() { + BeginX = EndX = CapacityX = &FirstEl; + } void setEnd(T *P) { this->EndX = P; } public: @@ -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(); diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index 89774c3..306e928 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -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; diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h index 55696333..063c675 100644 --- a/include/llvm/ADT/SparseSet.h +++ b/include/llvm/ADT/SparseSet.h @@ -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; diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 655d884..bf27c43 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -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 diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index cd84603..292bde0 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -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); } diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h index 9c55f6b..b69a964 100644 --- a/include/llvm/ADT/StringSet.h +++ b/include/llvm/ADT/StringSet.h @@ -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; } }; } diff --git a/include/llvm/ADT/Trie.h b/include/llvm/ADT/Trie.h deleted file mode 100644 index 845af01..0000000 --- a/include/llvm/ADT/Trie.h +++ /dev/null @@ -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 diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 7f7061a..408d70c 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.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); - /// @} }; diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index 9101df8..cc290d5 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -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; /// @} diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h index f7e2551..d23fccf 100644 --- a/include/llvm/ADT/ValueMap.h +++ b/include/llvm/ADT/ValueMap.h @@ -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; diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index ba9864a..7f5cd17 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -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; diff --git a/include/llvm/AddressingMode.h b/include/llvm/AddressingMode.h new file mode 100644 index 0000000..70b3c05 --- /dev/null +++ b/include/llvm/AddressingMode.h @@ -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 diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 674868a..be274af 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -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; diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 95626d6..1e606c8 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -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; diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 006daa0..c0567da 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -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; @@ -52,6 +55,12 @@ public: /// 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; /// \brief Test if an edge is hot relative to other out-edges of the Src. @@ -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 diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index fb77da7..6a9ed31 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -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: diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h index 9b5e842..2889269 100644 --- a/include/llvm/Analysis/CaptureTracking.h +++ b/include/llvm/Analysis/CaptureTracking.h @@ -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 diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 03c807c..4398faa 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -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); }; } diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index 2fdef5f..12e623e 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -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 diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h new file mode 100644 index 0000000..b4327ee --- /dev/null +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -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 diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index a1cc196..8940971 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -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, diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 2bf79b9..9b98013 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -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 diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 0cba135..a075db3 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -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. diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 152e885..e561e37 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -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 diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h index df7313f..bce84be 100644 --- a/include/llvm/Analysis/IntervalPartition.h +++ b/include/llvm/Analysis/IntervalPartition.h @@ -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 { diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h index 065c230..197e94e 100644 --- a/include/llvm/Analysis/LazyValueInfo.h +++ b/include/llvm/Analysis/LazyValueInfo.h @@ -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) { diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index 5f0aefb..afc90c2 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -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 diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h deleted file mode 100644 index f195d27..0000000 --- a/include/llvm/Analysis/LoopDependenceAnalysis.h +++ /dev/null @@ -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 */ diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index eeb482d..c5d7b01 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.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 diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index c07fbf7..3bb96f9 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -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), diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index e674e74..a842898 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -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) { diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 7e049d6..a715eae 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -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, diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index ff9a247..5a77fce 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -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); diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index a22bd12..27726f4 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -103,6 +103,14 @@ namespace llvm { //===--------------------------------------------------------------------===// // + // 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". // ImmutablePass *createNoProfileInfoPass(); @@ -172,11 +180,20 @@ namespace llvm { //===--------------------------------------------------------------------===// // - // createLoopDependenceAnalysisPass - This creates an instance of the - // LoopDependenceAnalysis pass. + // createDependenceAnalysisPass - This creates an instance of the + // DependenceAnalysis pass. + // + FunctionPass *createDependenceAnalysisPass(); + + //===--------------------------------------------------------------------===// + // + // createCostModelAnalysisPass - This creates an instance of the + // CostModelAnalysis pass. // - LoopPass *createLoopDependenceAnalysisPass(); + FunctionPass *createCostModelAnalysisPass(); + //===--------------------------------------------------------------------===// + // // Minor pass prototypes, allowing us to expose them through bugpoint and // analyze. FunctionPass *createInstCountPass(); diff --git a/include/llvm/Analysis/ProfileDataLoader.h b/include/llvm/Analysis/ProfileDataLoader.h new file mode 100644 index 0000000..9efbafc --- /dev/null +++ b/include/llvm/Analysis/ProfileDataLoader.h @@ -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 diff --git a/include/llvm/Analysis/ProfileDataTypes.h b/include/llvm/Analysis/ProfileDataTypes.h new file mode 100644 index 0000000..1be15e0 --- /dev/null +++ b/include/llvm/Analysis/ProfileDataTypes.h @@ -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 */ diff --git a/include/llvm/Analysis/ProfileInfoTypes.h b/include/llvm/Analysis/ProfileInfoTypes.h index 6b4ac85..45aab5b 100644 --- a/include/llvm/Analysis/ProfileInfoTypes.h +++ b/include/llvm/Analysis/ProfileInfoTypes.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. diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 188d11c..48d7ee6 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -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; diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index c213ade..235adca0 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -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; diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index ded1297..54db7d6 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -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; } diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h index c3c2f4b..b758eca 100644 --- a/include/llvm/Analysis/SparsePropagation.h +++ b/include/llvm/Analysis/SparsePropagation.h @@ -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) {} diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index e8d45f6..a857524 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -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 diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index e66075c..b1c2218 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -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; } diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 223aa00..a9c2d74 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -21,268 +21,280 @@ #include <string> namespace llvm { -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 +class AttrBuilder; +class AttributesImpl; +class LLVMContext; +class Type; /// 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; +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; } - bool operator != (const Attributes &Attrs) const { - return Bits != Attrs.Bits; + + /// 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 Attributes &Attrs) const { - return Attributes(Bits | Attrs.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); } - Attributes operator & (const Attributes &Attrs) const { - return Attributes(Bits & Attrs.Bits); + + /// @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); } - Attributes operator ^ (const Attributes &Attrs) const { - return Attributes(Bits ^ Attrs.Bits); + + bool operator==(const Attributes &A) const { + return Attrs == A.Attrs; } - Attributes &operator |= (const Attributes &Attrs) { - Bits |= Attrs.Bits; - return *this; + bool operator!=(const Attributes &A) const { + return Attrs != A.Attrs; } - Attributes &operator &= (const Attributes &Attrs) { - Bits &= Attrs.Bits; - return *this; + + 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); } - Attributes operator ~ () const { return Attributes(~Bits); } + uint64_t Raw() const { return Bits; } - private: - // Currently, we need less than 64 bits. - uint64_t Bits; -}; -namespace Attribute { - -/// 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} + bool operator==(const AttrBuilder &B) { + return Bits == B.Bits; + } + bool operator!=(const AttrBuilder &B) { + return Bits != B.Bits; + } }; -/// @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. -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. +//===----------------------------------------------------------------------===// +// AttributeWithIndex +//===----------------------------------------------------------------------===// +/// 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. + + 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 diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index d2aa167..02c2a96 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -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; } diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h index 3c75e58..4fd4b5d 100644 --- a/include/llvm/Bitcode/Archive.h +++ b/include/llvm/Bitcode/Archive.h @@ -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; /// @} }; diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 6586829..840f57e 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -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)); diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 475da13..dea118f 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -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) { diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index a8c34cb..c1dc190 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -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 diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h index 4c5ee62..053f4eb 100644 --- a/include/llvm/CallingConv.h +++ b/include/llvm/CallingConv.h @@ -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 diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 170a528..a92b859 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -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. diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 3afe309..436918b1 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -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; } diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h new file mode 100644 index 0000000..90ee234 --- /dev/null +++ b/include/llvm/CodeGen/CommandFlags.h @@ -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 diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 7cb9695..7c24e36 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -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; diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 20e33f7..076f6f3 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -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). diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h index 17a2653..4a6b5ac 100644 --- a/include/llvm/CodeGen/GCMetadataPrinter.h +++ b/include/llvm/CodeGen/GCMetadataPrinter.h @@ -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; } diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index f387bd5..5d0a3b4 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -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 diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h index 767b666..5a3fb4b 100644 --- a/include/llvm/CodeGen/IntrinsicLowering.h +++ b/include/llvm/CodeGen/IntrinsicLowering.h @@ -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 diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index a3ce47c..185e414 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -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. diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index da521db..b421753 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -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. // diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index d4bb409..3bb134b 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -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; diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index c917bd8..97c3945 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -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... diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index af4db7d..12189ce 100644 --- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -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. diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index d6d65a2..8ed215d 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -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(); diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 8b958e4..0e4e132 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -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; } diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 062c750..025e18a 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -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; } diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 27756ab..7eb03a9 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -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(); diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 654361f..7706853 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -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()); + } } } }; diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h index dc5f9a6..854ba06 100644 --- a/include/llvm/CodeGen/MachineInstrBundle.h +++ b/include/llvm/CodeGen/MachineInstrBundle.h @@ -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. diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index f7c4e86..928145d 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -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. /// diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 3e204be..d53f041 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -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 diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 1ac9080..ddb1271 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -151,6 +151,15 @@ public: bool isNonTemporal() const { return Flags & MONonTemporal; } bool isInvariant() const { return Flags & MOInvariant; } + /// isUnordered - Returns true if this memory operation doesn't have any + /// ordering constraints other than normal aliasing. Volatile and atomic + /// memory operations can't be reordered. + /// + /// Currently, we don't model the difference between volatile and atomic + /// operations. They should retain their ordering relative to all memory + /// operations. + bool isUnordered() const { return !isVolatile(); } + /// refineAlignment - Update this MachineMemOperand to reflect the alignment /// of MMO, if it has a greater alignment. This must only be used when the /// new alignment applies to all users of this MachineMemOperand. diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index 9401ffd1..7afc7eb 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -38,7 +38,7 @@ namespace llvm { /// this GV is external. DenseMap<MCSymbol*, StubValueTy> HiddenGVStubs; - virtual void Anchor(); // Out of line virtual method. + virtual void anchor(); // Out of line virtual method. public: MachineModuleInfoMachO(const MachineModuleInfo &) {} @@ -76,7 +76,7 @@ namespace llvm { /// mode. DenseMap<MCSymbol*, StubValueTy> GVStubs; - virtual void Anchor(); // Out of line virtual method. + virtual void anchor(); // Out of line virtual method. public: MachineModuleInfoELF(const MachineModuleInfo &) {} diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 37d42b3..606833c 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -14,7 +14,6 @@ #ifndef LLVM_CODEGEN_MACHINEOPERAND_H #define LLVM_CODEGEN_MACHINEOPERAND_H -#include "llvm/ADT/Hashing.h" #include "llvm/Support/DataTypes.h" #include <cassert> @@ -30,6 +29,7 @@ class MachineRegisterInfo; class MDNode; class TargetMachine; class TargetRegisterInfo; +class hash_code; class raw_ostream; class MCSymbol; @@ -60,12 +60,20 @@ private: /// union. unsigned char OpKind; // MachineOperandType - /// SubReg - Subregister number, only valid for MO_Register. A value of 0 - /// indicates the MO_Register has no subReg. - unsigned char SubReg; + // This union is discriminated by OpKind. + union { + /// SubReg - Subregister number, only valid for MO_Register. A value of 0 + /// indicates the MO_Register has no subReg. + unsigned char SubReg; + + /// TargetFlags - This is a set of target-specific operand flags. + unsigned char TargetFlags; + }; - /// TargetFlags - This is a set of target-specific operand flags. - unsigned char TargetFlags; + /// TiedTo - Non-zero when this register operand is tied to another register + /// operand. The encoding of this field is described in the block comment + /// before MachineInstr::tieOperands(). + unsigned char TiedTo : 4; /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register /// operands. @@ -176,9 +184,17 @@ public: /// MachineOperandType getType() const { return (MachineOperandType)OpKind; } - unsigned char getTargetFlags() const { return TargetFlags; } - void setTargetFlags(unsigned char F) { TargetFlags = F; } - void addTargetFlag(unsigned char F) { TargetFlags |= F; } + unsigned char getTargetFlags() const { + return isReg() ? 0 : TargetFlags; + } + void setTargetFlags(unsigned char F) { + assert(!isReg() && "Register operands can't have target flags"); + TargetFlags = F; + } + void addTargetFlag(unsigned char F) { + assert(!isReg() && "Register operands can't have target flags"); + TargetFlags |= F; + } /// getParent - Return the instruction that this operand belongs to. @@ -288,6 +304,11 @@ public: return IsEarlyClobber; } + bool isTied() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return TiedTo; + } + bool isDebug() const { assert(isReg() && "Wrong MachineOperand accessor"); return IsDebug; @@ -421,7 +442,7 @@ public: int64_t getOffset() const { assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || isBlockAddress()) && "Wrong MachineOperand accessor"); - return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) | + return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) | SmallContents.OffsetLo; } @@ -548,6 +569,7 @@ public: Op.IsUndef = isUndef; Op.IsInternalRead = isInternalRead; Op.IsEarlyClobber = isEarlyClobber; + Op.TiedTo = 0; Op.IsDebug = isDebug; Op.SmallContents.RegNo = Reg; Op.Contents.Reg.Prev = 0; @@ -606,11 +628,11 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateBA(const BlockAddress *BA, + static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_BlockAddress); Op.Contents.OffsetedInfo.Val.BA = BA; - Op.setOffset(0); // Offset is always 0. + Op.setOffset(Offset); Op.setTargetFlags(TargetFlags); return Op; } @@ -665,6 +687,9 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { return OS; } + // See friend declaration above. This additional declaration is required in + // order to compile LLVM with IBM xlC compiler. + hash_code hash_value(const MachineOperand &MO); } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h new file mode 100644 index 0000000..a9fc843 --- /dev/null +++ b/include/llvm/CodeGen/MachinePostDominators.h @@ -0,0 +1,87 @@ +//=- llvm/CodeGen/MachineDominators.h ----------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file exposes interfaces to post dominance information for +// target-specific code. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H +#define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H + +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominatorInternals.h" + +namespace llvm { + +/// +/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used +/// to compute the a post-dominator tree. +/// +struct MachinePostDominatorTree : public MachineFunctionPass { +private: + DominatorTreeBase<MachineBasicBlock> *DT; + +public: + static char ID; + + MachinePostDominatorTree(); + + ~MachinePostDominatorTree(); + + FunctionPass *createMachinePostDominatorTreePass(); + + const std::vector<MachineBasicBlock *> &getRoots() const { + return DT->getRoots(); + } + + MachineDomTreeNode *getRootNode() const { + return DT->getRootNode(); + } + + MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { + return DT->getNode(BB); + } + + MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { + return DT->getNode(BB); + } + + bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const { + return DT->dominates(A, B); + } + + bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const { + return DT->dominates(A, B); + } + + bool + properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) const { + return DT->properlyDominates(A, B); + } + + bool + properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const { + return DT->properlyDominates(A, B); + } + + MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, + MachineBasicBlock *B) { + return DT->findNearestCommonDominator(A, B); + } + + virtual bool runOnMachineFunction(MachineFunction &MF); + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const; +}; +} //end of namespace llvm + +#endif diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 42a8aa4..4e86363 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -77,16 +77,20 @@ class MachineRegisterInfo { return MO->Contents.Reg.Next; } - /// UsedPhysRegs - This is a bit vector that is computed and set by the + /// UsedRegUnits - This is a bit vector that is computed and set by the /// register allocator, and must be kept up to date by passes that run after /// register allocation (though most don't modify this). This is used /// so that the code generator knows which callee save registers to save and /// for other target specific uses. - /// This vector only has bits set for registers explicitly used, not their - /// aliases. - BitVector UsedPhysRegs; - - /// UsedPhysRegMask - Additional used physregs, but including aliases. + /// This vector has bits set for register units that are modified in the + /// current function. It doesn't include registers clobbered by function + /// calls with register mask operands. + BitVector UsedRegUnits; + + /// UsedPhysRegMask - Additional used physregs including aliases. + /// This bit vector represents all the registers clobbered by function calls. + /// It can model things that UsedRegUnits can't, such as function calls that + /// clobber ymm7 but preserve the low half in xmm7. BitVector UsedPhysRegMask; /// ReservedRegs - This is a bit vector of reserved registers. The target @@ -95,9 +99,6 @@ class MachineRegisterInfo { /// started. BitVector ReservedRegs; - /// AllocatableRegs - From TRI->getAllocatableSet. - mutable BitVector AllocatableRegs; - /// LiveIns/LiveOuts - Keep track of the physical registers that are /// livein/liveout of the function. Live in values are typically arguments in /// registers, live out values are typically return values in registers. @@ -106,8 +107,8 @@ class MachineRegisterInfo { std::vector<std::pair<unsigned, unsigned> > LiveIns; std::vector<unsigned> LiveOuts; - MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT - void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT + MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; + void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; public: explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); ~MachineRegisterInfo(); @@ -360,29 +361,27 @@ public: //===--------------------------------------------------------------------===// /// isPhysRegUsed - Return true if the specified register is used in this - /// function. This only works after register allocation. + /// function. Also check for clobbered aliases and registers clobbered by + /// function calls with register mask operands. + /// + /// This only works after register allocation. It is primarily used by + /// PrologEpilogInserter to determine which callee-saved registers need + /// spilling. bool isPhysRegUsed(unsigned Reg) const { - return UsedPhysRegs.test(Reg) || UsedPhysRegMask.test(Reg); - } - - /// isPhysRegOrOverlapUsed - Return true if Reg or any overlapping register - /// is used in this function. - bool isPhysRegOrOverlapUsed(unsigned Reg) const { if (UsedPhysRegMask.test(Reg)) return true; - for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) - if (UsedPhysRegs.test(*AI)) + for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) + if (UsedRegUnits.test(*Units)) return true; return false; } /// setPhysRegUsed - Mark the specified register used in this function. /// This should only be called during and after register allocation. - void setPhysRegUsed(unsigned Reg) { UsedPhysRegs.set(Reg); } - - /// addPhysRegsUsed - Mark the specified registers used in this function. - /// This should only be called during and after register allocation. - void addPhysRegsUsed(const BitVector &Regs) { UsedPhysRegs |= Regs; } + void setPhysRegUsed(unsigned Reg) { + for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) + UsedRegUnits.set(*Units); + } /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used. /// This corresponds to the bit mask attached to register mask operands. @@ -393,8 +392,9 @@ public: /// setPhysRegUnused - Mark the specified register unused in this function. /// This should only be called during and after register allocation. void setPhysRegUnused(unsigned Reg) { - UsedPhysRegs.reset(Reg); UsedPhysRegMask.reset(Reg); + for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) + UsedRegUnits.reset(*Units); } @@ -427,6 +427,34 @@ public: return !reservedRegsFrozen() || ReservedRegs.test(PhysReg); } + /// getReservedRegs - Returns a reference to the frozen set of reserved + /// registers. This method should always be preferred to calling + /// TRI::getReservedRegs() when possible. + const BitVector &getReservedRegs() const { + assert(reservedRegsFrozen() && + "Reserved registers haven't been frozen yet. " + "Use TRI::getReservedRegs()."); + return ReservedRegs; + } + + /// isReserved - Returns true when PhysReg is a reserved register. + /// + /// Reserved registers may belong to an allocatable register class, but the + /// target has explicitly requested that they are not used. + /// + bool isReserved(unsigned PhysReg) const { + return getReservedRegs().test(PhysReg); + } + + /// isAllocatable - Returns true when PhysReg belongs to an allocatable + /// register class and it hasn't been reserved. + /// + /// Allocatable registers may show up in the allocation order of some virtual + /// register, so a register allocator needs to track its liveness and + /// availability. + bool isAllocatable(unsigned PhysReg) const { + return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); + } //===--------------------------------------------------------------------===// // LiveIn/LiveOut Management diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h index cbb45a7..edf93d1 100644 --- a/include/llvm/CodeGen/MachineSSAUpdater.h +++ b/include/llvm/CodeGen/MachineSSAUpdater.h @@ -14,6 +14,8 @@ #ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H #define LLVM_CODEGEN_MACHINESSAUPDATER_H +#include "llvm/Support/Compiler.h" + namespace llvm { class MachineBasicBlock; class MachineFunction; @@ -106,8 +108,8 @@ private: void ReplaceRegWith(unsigned OldReg, unsigned NewReg); unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB); - void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT - MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT + void operator=(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION; + MachineSSAUpdater(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION; }; } // End llvm namespace diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 8da2045..31bd606 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -28,9 +28,15 @@ #define MACHINESCHEDULER_H #include "llvm/CodeGen/MachinePassRegistry.h" +#include "llvm/CodeGen/RegisterPressure.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/Target/TargetInstrInfo.h" namespace llvm { +extern cl::opt<bool> ForceTopDown; +extern cl::opt<bool> ForceBottomUp; + class AliasAnalysis; class LiveIntervals; class MachineDominatorTree; @@ -93,6 +99,237 @@ public: } }; +class ScheduleDAGMI; + +/// MachineSchedStrategy - Interface to the scheduling algorithm used by +/// ScheduleDAGMI. +class MachineSchedStrategy { +public: + virtual ~MachineSchedStrategy() {} + + /// Initialize the strategy after building the DAG for a new region. + virtual void initialize(ScheduleDAGMI *DAG) = 0; + + /// Notify this strategy that all roots have been released (including those + /// that depend on EntrySU or ExitSU). + virtual void registerRoots() {} + + /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to + /// schedule the node at the top of the unscheduled region. Otherwise it will + /// be scheduled at the bottom. + virtual SUnit *pickNode(bool &IsTopNode) = 0; + + /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an + /// instruction and updated scheduled/remaining flags in the DAG nodes. + virtual void schedNode(SUnit *SU, bool IsTopNode) = 0; + + /// When all predecessor dependencies have been resolved, free this node for + /// top-down scheduling. + virtual void releaseTopNode(SUnit *SU) = 0; + /// When all successor dependencies have been resolved, free this node for + /// bottom-up scheduling. + virtual void releaseBottomNode(SUnit *SU) = 0; +}; + +/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience +/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified +/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in. +/// +/// This is a convenience class that may be used by implementations of +/// MachineSchedStrategy. +class ReadyQueue { + unsigned ID; + std::string Name; + std::vector<SUnit*> Queue; + +public: + ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {} + + unsigned getID() const { return ID; } + + StringRef getName() const { return Name; } + + // SU is in this queue if it's NodeQueueID is a superset of this ID. + bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); } + + bool empty() const { return Queue.empty(); } + + void clear() { Queue.clear(); } + + unsigned size() const { return Queue.size(); } + + typedef std::vector<SUnit*>::iterator iterator; + + iterator begin() { return Queue.begin(); } + + iterator end() { return Queue.end(); } + + iterator find(SUnit *SU) { + return std::find(Queue.begin(), Queue.end(), SU); + } + + void push(SUnit *SU) { + Queue.push_back(SU); + SU->NodeQueueId |= ID; + } + + iterator remove(iterator I) { + (*I)->NodeQueueId &= ~ID; + *I = Queue.back(); + unsigned idx = I - Queue.begin(); + Queue.pop_back(); + return Queue.begin() + idx; + } + +#ifndef NDEBUG + void dump(); +#endif +}; + +/// Mutate the DAG as a postpass after normal DAG building. +class ScheduleDAGMutation { +public: + virtual ~ScheduleDAGMutation() {} + + virtual void apply(ScheduleDAGMI *DAG) = 0; +}; + +/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules +/// machine instructions while updating LiveIntervals and tracking regpressure. +class ScheduleDAGMI : public ScheduleDAGInstrs { +protected: + AliasAnalysis *AA; + RegisterClassInfo *RegClassInfo; + MachineSchedStrategy *SchedImpl; + + /// Ordered list of DAG postprocessing steps. + std::vector<ScheduleDAGMutation*> Mutations; + + MachineBasicBlock::iterator LiveRegionEnd; + + /// Register pressure in this region computed by buildSchedGraph. + IntervalPressure RegPressure; + RegPressureTracker RPTracker; + + /// List of pressure sets that exceed the target's pressure limit before + /// scheduling, listed in increasing set ID order. Each pressure set is paired + /// with its max pressure in the currently scheduled regions. + std::vector<PressureElement> RegionCriticalPSets; + + /// The top of the unscheduled zone. + MachineBasicBlock::iterator CurrentTop; + IntervalPressure TopPressure; + RegPressureTracker TopRPTracker; + + /// The bottom of the unscheduled zone. + MachineBasicBlock::iterator CurrentBottom; + IntervalPressure BotPressure; + RegPressureTracker BotRPTracker; + +#ifndef NDEBUG + /// The number of instructions scheduled so far. Used to cut off the + /// scheduler at the point determined by misched-cutoff. + unsigned NumInstrsScheduled; +#endif + +public: + ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): + ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), + AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), + RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure), + CurrentBottom(), BotRPTracker(BotPressure) { +#ifndef NDEBUG + NumInstrsScheduled = 0; +#endif + } + + virtual ~ScheduleDAGMI() { + delete SchedImpl; + } + + /// Add a postprocessing step to the DAG builder. + /// Mutations are applied in the order that they are added after normal DAG + /// building and before MachineSchedStrategy initialization. + void addMutation(ScheduleDAGMutation *Mutation) { + Mutations.push_back(Mutation); + } + + MachineBasicBlock::iterator top() const { return CurrentTop; } + MachineBasicBlock::iterator bottom() const { return CurrentBottom; } + + /// Implement the ScheduleDAGInstrs interface for handling the next scheduling + /// region. This covers all instructions in a block, while schedule() may only + /// cover a subset. + void enterRegion(MachineBasicBlock *bb, + MachineBasicBlock::iterator begin, + MachineBasicBlock::iterator end, + unsigned endcount); + + + /// Implement ScheduleDAGInstrs interface for scheduling a sequence of + /// reorderable instructions. + virtual void schedule(); + + /// Get current register pressure for the top scheduled instructions. + const IntervalPressure &getTopPressure() const { return TopPressure; } + const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; } + + /// Get current register pressure for the bottom scheduled instructions. + const IntervalPressure &getBotPressure() const { return BotPressure; } + const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; } + + /// Get register pressure for the entire scheduling region before scheduling. + const IntervalPressure &getRegPressure() const { return RegPressure; } + + const std::vector<PressureElement> &getRegionCriticalPSets() const { + return RegionCriticalPSets; + } + +protected: + // Top-Level entry points for the schedule() driver... + + /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking + /// enabled. This sets up three trackers. RPTracker will cover the entire DAG + /// region, TopTracker and BottomTracker will be initialized to the top and + /// bottom of the DAG region without covereing any unscheduled instruction. + void buildDAGWithRegPressure(); + + /// Apply each ScheduleDAGMutation step in order. This allows different + /// instances of ScheduleDAGMI to perform custom DAG postprocessing. + void postprocessDAG(); + + /// Identify DAG roots and setup scheduler queues. + void initQueues(); + + /// Move an instruction and update register pressure. + void scheduleMI(SUnit *SU, bool IsTopNode); + + /// Update scheduler DAG and queues after scheduling an instruction. + void updateQueues(SUnit *SU, bool IsTopNode); + + /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues. + void placeDebugValues(); + + /// \brief dump the scheduled Sequence. + void dumpSchedule() const; + + // Lesser helpers... + + void initRegPressure(); + + void updateScheduledPressure(std::vector<unsigned> NewMaxPressure); + + void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); + bool checkSchedLimit(); + + void releaseRoots(); + + void releaseSucc(SUnit *SU, SDep *SuccEdge); + void releaseSuccessors(SUnit *SU); + void releasePred(SUnit *SU, SDep *PredEdge); + void releasePredecessors(SUnit *SU); +}; + } // namespace llvm #endif diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index a5d8b0d..83c379b 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -19,6 +19,7 @@ #include <list> #include <map> +#include <llvm/ADT/ilist.h> namespace PBQP { @@ -31,16 +32,16 @@ namespace PBQP { class NodeEntry; class EdgeEntry; - typedef std::list<NodeEntry> NodeList; - typedef std::list<EdgeEntry> EdgeList; + typedef llvm::ilist<NodeEntry> NodeList; + typedef llvm::ilist<EdgeEntry> EdgeList; public: - typedef NodeList::iterator NodeItr; - typedef NodeList::const_iterator ConstNodeItr; + typedef NodeEntry* NodeItr; + typedef const NodeEntry* ConstNodeItr; - typedef EdgeList::iterator EdgeItr; - typedef EdgeList::const_iterator ConstEdgeItr; + typedef EdgeEntry* EdgeItr; + typedef const EdgeEntry* ConstEdgeItr; private: @@ -52,12 +53,14 @@ namespace PBQP { private: - class NodeEntry { + class NodeEntry : public llvm::ilist_node<NodeEntry> { + friend struct llvm::ilist_sentinel_traits<NodeEntry>; private: Vector costs; AdjEdgeList adjEdges; unsigned degree; void *data; + NodeEntry() : costs(0, 0) {} public: NodeEntry(const Vector &costs) : costs(costs), degree(0) {} Vector& getCosts() { return costs; } @@ -77,12 +80,14 @@ namespace PBQP { void* getData() { return data; } }; - class EdgeEntry { + class EdgeEntry : public llvm::ilist_node<EdgeEntry> { + friend struct llvm::ilist_sentinel_traits<EdgeEntry>; private: NodeItr node1, node2; Matrix costs; AdjEdgeItr node1AEItr, node2AEItr; void *data; + EdgeEntry() : costs(0, 0, 0) {} public: EdgeEntry(NodeItr node1, NodeItr node2, const Matrix &costs) : node1(node1), node2(node2), costs(costs) {} diff --git a/include/llvm/CodeGen/PBQP/HeuristicBase.h b/include/llvm/CodeGen/PBQP/HeuristicBase.h index 3fee18c..0c1fcb7 100644 --- a/include/llvm/CodeGen/PBQP/HeuristicBase.h +++ b/include/llvm/CodeGen/PBQP/HeuristicBase.h @@ -113,7 +113,7 @@ namespace PBQP { } /// \brief Add the given node to the list of nodes to be optimally reduced. - /// @return nItr Node iterator to be added. + /// @param nItr Node iterator to be added. /// /// You probably don't want to over-ride this, except perhaps to record /// statistics before calling this implementation. HeuristicBase relies on @@ -193,8 +193,9 @@ namespace PBQP { /// reduce list. /// @return True if a reduction takes place, false if the heuristic reduce /// list is empty. - void heuristicReduce() { + bool heuristicReduce() { llvm_unreachable("Must be implemented in derived class."); + return false; } /// \brief Prepare a change in the costs on the given edge. diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 07b3b45..7bd5764 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -404,6 +404,10 @@ namespace llvm { /// inserting cmov instructions. extern char &EarlyIfConverterID; + /// StackSlotColoring - This pass performs stack coloring and merging. + /// It merges disjoint allocas to reduce the stack size. + extern char &StackColoringID; + /// IfConverter - This pass performs machine code if conversion. extern char &IfConverterID; diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index 7dab4f9..8f52d3b 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -50,7 +50,6 @@ namespace llvm { /// classof - Methods for support type inquiry through isa, cast, and /// dyn_cast: /// - static inline bool classof(const PseudoSourceValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == PseudoSourceValueVal || V->getValueID() == FixedStackPseudoSourceValueVal; @@ -90,9 +89,6 @@ namespace llvm { /// classof - Methods for support type inquiry through isa, cast, and /// dyn_cast: /// - static inline bool classof(const FixedStackPseudoSourceValue *) { - return true; - } static inline bool classof(const Value *V) { return V->getValueID() == FixedStackPseudoSourceValueVal; } diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index bce3ec7..acfc07d 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -109,8 +109,8 @@ namespace llvm { /// class to support additional constraints for your architecture. class PBQPBuilder { private: - PBQPBuilder(const PBQPBuilder&) {} - void operator=(const PBQPBuilder&) {} + PBQPBuilder(const PBQPBuilder&) LLVM_DELETED_FUNCTION; + void operator=(const PBQPBuilder&) LLVM_DELETED_FUNCTION; public: typedef std::set<unsigned> RegSet; diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h index 400e1f4..4467b62 100644 --- a/include/llvm/CodeGen/RegisterClassInfo.h +++ b/include/llvm/CodeGen/RegisterClassInfo.h @@ -106,25 +106,6 @@ public: return CalleeSaved[N-1]; return 0; } - - /// isReserved - Returns true when PhysReg is a reserved register. - /// - /// Reserved registers may belong to an allocatable register class, but the - /// target has explicitly requested that they are not used. - /// - bool isReserved(unsigned PhysReg) const { - return Reserved.test(PhysReg); - } - - /// isAllocatable - Returns true when PhysReg belongs to an allocatable - /// register class and it hasn't been reserved. - /// - /// Allocatable registers may show up in the allocation order of some virtual - /// register, so a register allocator needs to track its liveness and - /// availability. - bool isAllocatable(unsigned PhysReg) const { - return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); - } }; } // end namespace llvm diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h index 2043155..30326d0 100644 --- a/include/llvm/CodeGen/RegisterPressure.h +++ b/include/llvm/CodeGen/RegisterPressure.h @@ -43,7 +43,7 @@ struct RegisterPressure { /// class. This is only useful to account for spilling or rematerialization. void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI); - void dump(const TargetRegisterInfo *TRI); + void dump(const TargetRegisterInfo *TRI) const; }; /// RegisterPressure computed within a region of instructions delimited by @@ -197,6 +197,7 @@ public: /// This result is complete if either advance() or recede() has returned true, /// or if closeRegion() was explicitly invoked. RegisterPressure &getPressure() { return P; } + const RegisterPressure &getPressure() const { return P; } /// Get the register set pressure at the current position, which may be less /// than the pressure across the traversed region. diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 3986a8d..08d3169 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -18,6 +18,7 @@ #define LLVM_CODEGEN_REGISTER_SCAVENGING_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/ADT/BitVector.h" namespace llvm { @@ -59,10 +60,6 @@ class RegScavenger { /// BitVector CalleeSavedRegs; - /// ReservedRegs - A bitvector of reserved registers. - /// - BitVector ReservedRegs; - /// RegsAvailable - The current state of all the physical registers immediately /// before MBBI. One bit per physical register. If bit is set that means it's /// available, unset means the register is currently being used. @@ -130,12 +127,12 @@ public: void setUsed(unsigned Reg); private: /// isReserved - Returns true if a register is reserved. It is never "unused". - bool isReserved(unsigned Reg) const { return ReservedRegs.test(Reg); } + bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } /// isUsed / isUnused - Test if a register is currently being used. /// bool isUsed(unsigned Reg) const { - return !RegsAvailable.test(Reg) || ReservedRegs.test(Reg); + return !RegsAvailable.test(Reg) || isReserved(Reg); } /// isAliasUsed - Is Reg or an alias currently in use? diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 85ab47b..7e0ca14 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -31,6 +31,7 @@ namespace llvm { class MachineFunction; class MachineRegisterInfo; class MachineInstr; + struct MCSchedClassDesc; class TargetRegisterInfo; class ScheduleDAG; class SDNode; @@ -52,6 +53,13 @@ namespace llvm { Order ///< Any other ordering dependency. }; + enum OrderKind { + Barrier, ///< An unknown scheduling barrier. + MayAliasMem, ///< Nonvolatile load/Store instructions that may alias. + MustAliasMem, ///< Nonvolatile load/Store instructions that must alias. + Artificial ///< Arbitrary weak DAG edge (no actual dependence). + }; + private: /// Dep - A pointer to the depending/depended-on SUnit, and an enum /// indicating the kind of the dependency. @@ -65,26 +73,18 @@ namespace llvm { unsigned Reg; /// Order - Additional information about Order dependencies. - struct { - /// isNormalMemory - True if both sides of the dependence - /// access memory in non-volatile and fully modeled ways. - bool isNormalMemory : 1; - - /// isMustAlias - True if both sides of the dependence are known to - /// access the same memory. - bool isMustAlias : 1; - - /// isArtificial - True if this is an artificial dependency, meaning - /// it is not necessary for program correctness, and may be safely - /// deleted if necessary. - bool isArtificial : 1; - } Order; + unsigned OrdKind; // enum OrderKind } Contents; /// Latency - The time associated with this edge. Often this is just /// the value of the Latency field of the predecessor, however advanced /// models may provide additional information about specific edges. unsigned Latency; + /// Record MinLatency seperately from "expected" Latency. + /// + /// FIXME: this field is not packed on LP64. Convert to 16-bit DAG edge + /// latency after introducing saturating truncation. + unsigned MinLatency; public: /// SDep - Construct a null SDep. This is only for use by container @@ -93,28 +93,28 @@ namespace llvm { SDep() : Dep(0, Data) {} /// SDep - Construct an SDep with the specified values. - SDep(SUnit *S, Kind kind, unsigned latency = 1, unsigned Reg = 0, - bool isNormalMemory = false, bool isMustAlias = false, - bool isArtificial = false) - : Dep(S, kind), Contents(), Latency(latency) { + SDep(SUnit *S, Kind kind, unsigned Reg) + : Dep(S, kind), Contents() { switch (kind) { + default: + llvm_unreachable("Reg given for non-register dependence!"); case Anti: case Output: assert(Reg != 0 && "SDep::Anti and SDep::Output must use a non-zero Reg!"); - // fall through - case Data: - assert(!isMustAlias && "isMustAlias only applies with SDep::Order!"); - assert(!isArtificial && "isArtificial only applies with SDep::Order!"); Contents.Reg = Reg; + Latency = 0; break; - case Order: - assert(Reg == 0 && "Reg given for non-register dependence!"); - Contents.Order.isNormalMemory = isNormalMemory; - Contents.Order.isMustAlias = isMustAlias; - Contents.Order.isArtificial = isArtificial; + case Data: + Contents.Reg = Reg; + Latency = 1; break; } + MinLatency = Latency; + } + SDep(SUnit *S, OrderKind kind) + : Dep(S, Order), Contents(), Latency(0), MinLatency(0) { + Contents.OrdKind = kind; } /// Return true if the specified SDep is equivalent except for latency. @@ -126,16 +126,14 @@ namespace llvm { case Output: return Contents.Reg == Other.Contents.Reg; case Order: - return Contents.Order.isNormalMemory == - Other.Contents.Order.isNormalMemory && - Contents.Order.isMustAlias == Other.Contents.Order.isMustAlias && - Contents.Order.isArtificial == Other.Contents.Order.isArtificial; + return Contents.OrdKind == Other.Contents.OrdKind; } llvm_unreachable("Invalid dependency kind!"); } bool operator==(const SDep &Other) const { - return overlaps(Other) && Latency == Other.Latency; + return overlaps(Other) + && Latency == Other.Latency && MinLatency == Other.MinLatency; } bool operator!=(const SDep &Other) const { @@ -155,6 +153,18 @@ namespace llvm { Latency = Lat; } + /// getMinLatency - Return the minimum latency for this edge. Minimum + /// latency is used for scheduling groups, while normal (expected) latency + /// is for instruction cost and critical path. + unsigned getMinLatency() const { + return MinLatency; + } + + /// setMinLatency - Set the minimum latency for this edge. + void setMinLatency(unsigned Lat) { + MinLatency = Lat; + } + //// getSUnit - Return the SUnit to which this edge points. SUnit *getSUnit() const { return Dep.getPointer(); @@ -179,20 +189,21 @@ namespace llvm { /// memory accesses where both sides of the dependence access memory /// in non-volatile and fully modeled ways. bool isNormalMemory() const { - return getKind() == Order && Contents.Order.isNormalMemory; + return getKind() == Order && (Contents.OrdKind == MayAliasMem + || Contents.OrdKind == MustAliasMem); } /// isMustAlias - Test if this is an Order dependence that is marked /// as "must alias", meaning that the SUnits at either end of the edge /// have a memory dependence on a known memory location. bool isMustAlias() const { - return getKind() == Order && Contents.Order.isMustAlias; + return getKind() == Order && Contents.OrdKind == MustAliasMem; } /// isArtificial - Test if this is an Order dependence that is marked /// as "artificial", meaning it isn't necessary for correctness. bool isArtificial() const { - return getKind() == Order && Contents.Order.isArtificial; + return getKind() == Order && Contents.OrdKind == Artificial; } /// isAssignedRegDep - Test if this is a Data dependence that is @@ -239,6 +250,8 @@ namespace llvm { // this node was cloned. // (SD scheduling only) + const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass. + // Preds/Succs - The SUnits before/after us in the graph. SmallVector<SDep, 4> Preds; // All sunit predecessors. SmallVector<SDep, 4> Succs; // All sunit successors. @@ -286,7 +299,7 @@ namespace llvm { /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent /// an SDNode and any nodes flagged to it. SUnit(SDNode *node, unsigned nodenum) - : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), + : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), @@ -300,7 +313,7 @@ namespace llvm { /// SUnit - Construct an SUnit for post-regalloc scheduling to represent /// a MachineInstr. SUnit(MachineInstr *instr, unsigned nodenum) - : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), + : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), @@ -313,7 +326,7 @@ namespace llvm { /// SUnit - Construct a placeholder SUnit. SUnit() - : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), + : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), @@ -555,16 +568,6 @@ namespace llvm { unsigned VerifyScheduledDAG(bool isBottomUp); #endif - protected: - /// ComputeLatency - Compute node latency. - /// - virtual void computeLatency(SUnit *SU) = 0; - - /// ForceUnitLatencies - Return true if all scheduling edges should be given - /// a latency value of one. The default is to return false; schedulers may - /// override this as needed. - virtual bool forceUnitLatencies() const { return false; } - private: // Return the MCInstrDesc of this SDNode or NULL. const MCInstrDesc *getNodeDesc(const SDNode *Node) const; diff --git a/include/llvm/CodeGen/ScheduleDAGILP.h b/include/llvm/CodeGen/ScheduleDAGILP.h new file mode 100644 index 0000000..1aa4058 --- /dev/null +++ b/include/llvm/CodeGen/ScheduleDAGILP.h @@ -0,0 +1,86 @@ +//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of an ILP metric for machine level instruction scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H +#define LLVM_CODEGEN_SCHEDULEDAGILP_H + +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { + +class raw_ostream; +class ScheduleDAGInstrs; +class SUnit; + +/// \brief Represent the ILP of the subDAG rooted at a DAG node. +struct ILPValue { + unsigned InstrCount; + unsigned Cycles; + + ILPValue(): InstrCount(0), Cycles(0) {} + + ILPValue(unsigned count, unsigned cycles): + InstrCount(count), Cycles(cycles) {} + + bool isValid() const { return Cycles > 0; } + + // Order by the ILP metric's value. + bool operator<(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Cycles + < (uint64_t)Cycles * RHS.InstrCount; + } + bool operator>(ILPValue RHS) const { + return RHS < *this; + } + bool operator<=(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Cycles + <= (uint64_t)Cycles * RHS.InstrCount; + } + bool operator>=(ILPValue RHS) const { + return RHS <= *this; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + void print(raw_ostream &OS) const; + + void dump() const; +#endif +}; + +/// \brief Compute the values of each DAG node for an ILP metric. +/// +/// This metric assumes that the DAG is a forest of trees with roots at the +/// bottom of the schedule. +class ScheduleDAGILP { + bool IsBottomUp; + std::vector<ILPValue> ILPValues; + +public: + ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {} + + /// \brief Initialize the result data with the size of the DAG. + void resize(unsigned NumSUnits); + + /// \brief Compute the ILP metric for the subDAG at this root. + void computeILP(const SUnit *Root); + + /// \brief Get the ILP value for a DAG node. + ILPValue getILP(const SUnit *SU); +}; + +raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); + +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index 1bde942..4bcd35a 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/TargetSchedule.h" #include "llvm/Support/Compiler.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/SmallSet.h" @@ -30,72 +31,6 @@ namespace llvm { class LiveIntervals; class RegPressureTracker; - /// LoopDependencies - This class analyzes loop-oriented register - /// dependencies, which are used to guide scheduling decisions. - /// For example, loop induction variable increments should be - /// scheduled as soon as possible after the variable's last use. - /// - class LoopDependencies { - const MachineDominatorTree &MDT; - - public: - typedef std::map<unsigned, std::pair<const MachineOperand *, unsigned> > - LoopDeps; - LoopDeps Deps; - - LoopDependencies(const MachineDominatorTree &mdt) : MDT(mdt) {} - - /// VisitLoop - Clear out any previous state and analyze the given loop. - /// - void VisitLoop(const MachineLoop *Loop) { - assert(Deps.empty() && "stale loop dependencies"); - - MachineBasicBlock *Header = Loop->getHeader(); - SmallSet<unsigned, 8> LoopLiveIns; - for (MachineBasicBlock::livein_iterator LI = Header->livein_begin(), - LE = Header->livein_end(); LI != LE; ++LI) - LoopLiveIns.insert(*LI); - - const MachineDomTreeNode *Node = MDT.getNode(Header); - const MachineBasicBlock *MBB = Node->getBlock(); - assert(Loop->contains(MBB) && - "Loop does not contain header!"); - VisitRegion(Node, MBB, Loop, LoopLiveIns); - } - - private: - void VisitRegion(const MachineDomTreeNode *Node, - const MachineBasicBlock *MBB, - const MachineLoop *Loop, - const SmallSet<unsigned, 8> &LoopLiveIns) { - unsigned Count = 0; - for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); - I != E; ++I) { - const MachineInstr *MI = I; - if (MI->isDebugValue()) - continue; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse()) - continue; - unsigned MOReg = MO.getReg(); - if (LoopLiveIns.count(MOReg)) - Deps.insert(std::make_pair(MOReg, std::make_pair(&MO, Count))); - } - ++Count; // Not every iteration due to dbg_value above. - } - - const std::vector<MachineDomTreeNode*> &Children = Node->getChildren(); - for (std::vector<MachineDomTreeNode*>::const_iterator I = - Children.begin(), E = Children.end(); I != E; ++I) { - const MachineDomTreeNode *ChildNode = *I; - MachineBasicBlock *ChildBlock = ChildNode->getBlock(); - if (Loop->contains(ChildBlock)) - VisitRegion(ChildNode, ChildBlock, Loop, LoopLiveIns); - } - } - }; - /// An individual mapping from virtual register number to SUnit. struct VReg2SUnit { unsigned VirtReg; @@ -108,6 +43,15 @@ namespace llvm { } }; + /// Record a physical register access. + /// For non data-dependent uses, OpIdx == -1. + struct PhysRegSUOper { + SUnit *SU; + int OpIdx; + + PhysRegSUOper(SUnit *su, int op): SU(su), OpIdx(op) {} + }; + /// Combine a SparseSet with a 1x1 vector to track physical registers. /// The SparseSet allows iterating over the (few) live registers for quickly /// comparing against a regmask or clearing the set. @@ -116,7 +60,7 @@ namespace llvm { /// cleared between scheduling regions without freeing unused entries. class Reg2SUnitsMap { SparseSet<unsigned> PhysRegSet; - std::vector<std::vector<SUnit*> > SUnits; + std::vector<std::vector<PhysRegSUOper> > SUnits; public: typedef SparseSet<unsigned>::const_iterator const_iterator; @@ -140,7 +84,7 @@ namespace llvm { /// If this register is mapped, return its existing SUnits vector. /// Otherwise map the register and return an empty SUnits vector. - std::vector<SUnit *> &operator[](unsigned Reg) { + std::vector<PhysRegSUOper> &operator[](unsigned Reg) { bool New = PhysRegSet.insert(Reg).second; assert((!New || SUnits[Reg].empty()) && "stale SUnits vector"); (void)New; @@ -167,11 +111,13 @@ namespace llvm { const MachineLoopInfo &MLI; const MachineDominatorTree &MDT; const MachineFrameInfo *MFI; - const InstrItineraryData *InstrItins; /// Live Intervals provides reaching defs in preRA scheduling. LiveIntervals *LIS; + /// TargetSchedModel provides an interface to the machine model. + TargetSchedModel SchedModel; + /// isPostRA flag indicates vregs cannot be present. bool IsPostRA; @@ -223,10 +169,6 @@ namespace llvm { /// to minimize construction/destruction. std::vector<SUnit *> PendingLoads; - /// LoopRegs - Track which registers are used for loop-carried dependencies. - /// - LoopDependencies LoopRegs; - /// DbgValues - Remember instruction that precedes DBG_VALUE. /// These are generated by buildSchedGraph but persist so they can be /// referenced when emitting the final schedule. @@ -244,6 +186,16 @@ namespace llvm { virtual ~ScheduleDAGInstrs() {} + /// \brief Get the machine model for instruction scheduling. + const TargetSchedModel *getSchedModel() const { return &SchedModel; } + + /// \brief Resolve and cache a resolved scheduling class for an SUnit. + const MCSchedClassDesc *getSchedClass(SUnit *SU) const { + if (!SU->SchedClass) + SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr()); + return SU->SchedClass; + } + /// begin - Return an iterator to the top of the current scheduling region. MachineBasicBlock::iterator begin() const { return RegionBegin; } @@ -284,20 +236,6 @@ namespace llvm { /// used by instructions in the fallthrough block. void addSchedBarrierDeps(); - /// computeLatency - Compute node latency. - /// - virtual void computeLatency(SUnit *SU); - - /// computeOperandLatency - Return dependence edge latency using - /// operand use/def information - /// - /// FindMin may be set to get the minimum vs. expected latency. Minimum - /// latency is used for scheduling groups, while expected latency is for - /// instruction cost and critical path. - virtual unsigned computeOperandLatency(SUnit *Def, SUnit *Use, - const SDep& dep, - bool FindMin = false) const; - /// schedule - Order nodes according to selected style, filling /// in the Sequence member. /// @@ -319,7 +257,7 @@ namespace llvm { protected: void initSUnits(); - void addPhysRegDataDeps(SUnit *SU, const MachineOperand &MO); + void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx); void addPhysRegDeps(SUnit *SU, unsigned OperIdx); void addVRegDefDeps(SUnit *SU, unsigned OperIdx); void addVRegUseDeps(SUnit *SU, unsigned OperIdx); diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h index a582b0c..836b73a 100644 --- a/include/llvm/CodeGen/SchedulerRegistry.h +++ b/include/llvm/CodeGen/SchedulerRegistry.h @@ -102,6 +102,11 @@ ScheduleDAGSDNodes *createVLIWDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel); +/// createDAGLinearizer - This creates a "no-scheduling" scheduler which +/// linearize the DAG using topological order. +ScheduleDAGSDNodes *createDAGLinearizer(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel); + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 1ccfe54..619ee69 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -73,8 +73,8 @@ class SDDbgInfo { SmallVector<SDDbgValue*, 32> ByvalParmDbgValues; DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap; - void operator=(const SDDbgInfo&); // Do not implement. - SDDbgInfo(const SDDbgInfo&); // Do not implement. + void operator=(const SDDbgInfo&) LLVM_DELETED_FUNCTION; + SDDbgInfo(const SDDbgInfo&) LLVM_DELETED_FUNCTION; public: SDDbgInfo() {} @@ -222,8 +222,8 @@ private: DenseSet<SDNode *> &visited, int level, bool &printed); - void operator=(const SelectionDAG&); // Do not implement. - SelectionDAG(const SelectionDAG&); // Do not implement. + void operator=(const SelectionDAG&) LLVM_DELETED_FUNCTION; + SelectionDAG(const SelectionDAG&) LLVM_DELETED_FUNCTION; public: explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level); @@ -437,7 +437,13 @@ public: SDValue getRegisterMask(const uint32_t *RegMask); SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label); SDValue getBlockAddress(const BlockAddress *BA, EVT VT, - bool isTarget = false, unsigned char TargetFlags = 0); + int64_t Offset = 0, bool isTarget = false, + unsigned char TargetFlags = 0); + SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, + int64_t Offset = 0, + unsigned char TargetFlags = 0) { + return getBlockAddress(BA, VT, Offset, true, TargetFlags); + } SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) { return getNode(ISD::CopyToReg, dl, MVT::Other, Chain, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index db361ee..362e9af 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -216,8 +216,8 @@ class SDUse { /// this operand. SDUse **Prev, *Next; - SDUse(const SDUse &U); // Do not implement - void operator=(const SDUse &U); // Do not implement + SDUse(const SDUse &U) LLVM_DELETED_FUNCTION; + void operator=(const SDUse &U) LLVM_DELETED_FUNCTION; public: SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {} @@ -662,9 +662,6 @@ public: /// void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const; - - static bool classof(const SDNode *) { return true; } - /// Profile - Gather unique data for the node. /// void Profile(FoldingSetNodeID &ID) const; @@ -956,7 +953,12 @@ public: const MachinePointerInfo &getPointerInfo() const { return MMO->getPointerInfo(); } - + + /// getAddressSpace - Return the address space for the associated pointer + unsigned getAddressSpace() const { + return getPointerInfo().getAddrSpace(); + } + /// refineAlignment - Update this MemSDNode's MachineMemOperand information /// to reflect the alignment of NewMMO, if it has a greater alignment. /// This must only be used when the new alignment applies to all users of @@ -971,7 +973,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const MemSDNode *) { return true; } static bool classof(const SDNode *N) { // For some targets, we lower some target intrinsics to a MemIntrinsicNode // with either an intrinsic or a target opcode. @@ -1011,11 +1012,6 @@ class AtomicSDNode : public MemSDNode { SubclassData |= SynchScope << 12; assert(getOrdering() == Ordering && "Ordering encoding error!"); assert(getSynchScope() == SynchScope && "Synch-scope encoding error!"); - - assert((readMem() || getOrdering() <= Monotonic) && - "Acquire/Release MachineMemOperand must be a load!"); - assert((writeMem() || getOrdering() <= Monotonic) && - "Acquire/Release MachineMemOperand must be a store!"); } public: @@ -1061,7 +1057,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const AtomicSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ATOMIC_CMP_SWAP || N->getOpcode() == ISD::ATOMIC_SWAP || @@ -1093,7 +1088,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const MemIntrinsicSDNode *) { return true; } static bool classof(const SDNode *N) { // We lower some target intrinsics to their target opcode // early a node with a target opcode can be of this class @@ -1148,7 +1142,6 @@ public: } static bool isSplatMask(const int *Mask, EVT VT); - static bool classof(const ShuffleVectorSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VECTOR_SHUFFLE; } @@ -1172,7 +1165,6 @@ public: bool isNullValue() const { return Value->isNullValue(); } bool isAllOnesValue() const { return Value->isAllOnesValue(); } - static bool classof(const ConstantSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::Constant || N->getOpcode() == ISD::TargetConstant; @@ -1207,9 +1199,6 @@ public: /// have to duplicate its logic everywhere it's called. bool isExactlyValue(double V) const { bool ignored; - // convert is not supported on this type - if (&Value->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) - return false; APFloat Tmp(V); Tmp.convert(Value->getValueAPF().getSemantics(), APFloat::rmNearestTiesToEven, &ignored); @@ -1219,7 +1208,6 @@ public: static bool isValueValidForType(EVT VT, const APFloat& Val); - static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ConstantFP || N->getOpcode() == ISD::TargetConstantFP; @@ -1241,7 +1229,6 @@ public: // Return the address space this GlobalAddress belongs to. unsigned getAddressSpace() const; - static bool classof(const GlobalAddressSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::GlobalAddress || N->getOpcode() == ISD::TargetGlobalAddress || @@ -1261,7 +1248,6 @@ public: int getIndex() const { return FI; } - static bool classof(const FrameIndexSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::FrameIndex || N->getOpcode() == ISD::TargetFrameIndex; @@ -1281,7 +1267,6 @@ public: int getIndex() const { return JTI; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const JumpTableSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::JumpTable || N->getOpcode() == ISD::TargetJumpTable; @@ -1342,7 +1327,6 @@ public: Type *getType() const; - static bool classof(const ConstantPoolSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ConstantPool || N->getOpcode() == ISD::TargetConstantPool; @@ -1366,7 +1350,6 @@ public: int getIndex() const { return Index; } int64_t getOffset() const { return Offset; } - static bool classof(const TargetIndexSDNode*) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::TargetIndex; } @@ -1385,7 +1368,6 @@ public: MachineBasicBlock *getBasicBlock() const { return MBB; } - static bool classof(const BasicBlockSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::BasicBlock; } @@ -1395,7 +1377,7 @@ public: /// BUILD_VECTORs. class BuildVectorSDNode : public SDNode { // These are constructed as SDNodes and then cast to BuildVectorSDNodes. - explicit BuildVectorSDNode(); // Do not implement + explicit BuildVectorSDNode() LLVM_DELETED_FUNCTION; public: /// isConstantSplat - Check if this is a constant splat, and if so, find the /// smallest element size that splats the vector. If MinSplatBits is @@ -1410,7 +1392,6 @@ public: unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits = 0, bool isBigEndian = false); - static inline bool classof(const BuildVectorSDNode *) { return true; } static inline bool classof(const SDNode *N) { return N->getOpcode() == ISD::BUILD_VECTOR; } @@ -1431,7 +1412,6 @@ public: /// getValue - return the contained Value. const Value *getValue() const { return V; } - static bool classof(const SrcValueSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::SRCVALUE; } @@ -1446,7 +1426,6 @@ public: const MDNode *getMD() const { return MD; } - static bool classof(const MDNodeSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::MDNODE_SDNODE; } @@ -1463,7 +1442,6 @@ public: unsigned getReg() const { return Reg; } - static bool classof(const RegisterSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::Register; } @@ -1480,7 +1458,6 @@ public: const uint32_t *getRegMask() const { return RegMask; } - static bool classof(const RegisterMaskSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::RegisterMask; } @@ -1488,18 +1465,19 @@ public: class BlockAddressSDNode : public SDNode { const BlockAddress *BA; + int64_t Offset; unsigned char TargetFlags; friend class SelectionDAG; BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba, - unsigned char Flags) + int64_t o, unsigned char Flags) : SDNode(NodeTy, DebugLoc(), getSDVTList(VT)), - BA(ba), TargetFlags(Flags) { + BA(ba), Offset(o), TargetFlags(Flags) { } public: const BlockAddress *getBlockAddress() const { return BA; } + int64_t getOffset() const { return Offset; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const BlockAddressSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::BlockAddress || N->getOpcode() == ISD::TargetBlockAddress; @@ -1517,7 +1495,6 @@ class EHLabelSDNode : public SDNode { public: MCSymbol *getLabel() const { return Label; } - static bool classof(const EHLabelSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::EH_LABEL; } @@ -1537,7 +1514,6 @@ public: const char *getSymbol() const { return Symbol; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const ExternalSymbolSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ExternalSymbol || N->getOpcode() == ISD::TargetExternalSymbol; @@ -1555,7 +1531,6 @@ public: ISD::CondCode get() const { return Condition; } - static bool classof(const CondCodeSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::CONDCODE; } @@ -1575,7 +1550,6 @@ class CvtRndSatSDNode : public SDNode { public: ISD::CvtCode getCvtCode() const { return CvtCode; } - static bool classof(const CvtRndSatSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::CONVERT_RNDSAT; } @@ -1594,7 +1568,6 @@ public: EVT getVT() const { return ValueType; } - static bool classof(const VTSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VALUETYPE; } @@ -1638,7 +1611,6 @@ public: /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store. bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } - static bool classof(const LSBaseSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE; @@ -1670,7 +1642,6 @@ public: const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getOffset() const { return getOperand(2); } - static bool classof(const LoadSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD; } @@ -1701,7 +1672,6 @@ public: const SDValue &getBasePtr() const { return getOperand(2); } const SDValue &getOffset() const { return getOperand(3); } - static bool classof(const StoreSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::STORE; } @@ -1742,7 +1712,6 @@ public: MemRefsEnd = NewMemRefsEnd; } - static bool classof(const MachineSDNode *) { return true; } static bool classof(const SDNode *N) { return N->isMachineOpcode(); } @@ -1750,10 +1719,10 @@ public: class SDNodeIterator : public std::iterator<std::forward_iterator_tag, SDNode, ptrdiff_t> { - SDNode *Node; + const SDNode *Node; unsigned Operand; - SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {} + SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {} public: bool operator==(const SDNodeIterator& x) const { return Operand == x.Operand; @@ -1784,8 +1753,8 @@ public: return Operand - Other.Operand; } - static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); } - static SDNodeIterator end (SDNode *N) { + static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); } + static SDNodeIterator end (const SDNode *N) { return SDNodeIterator(N, N->getNumOperands()); } diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h new file mode 100644 index 0000000..88e6105 --- /dev/null +++ b/include/llvm/CodeGen/TargetSchedule.h @@ -0,0 +1,167 @@ +//===-- llvm/CodeGen/TargetSchedule.h - Sched Machine Model -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a wrapper around MCSchedModel that allows the interface to +// benefit from information currently only available in TargetInstrInfo. +// Ideally, the scheduling interface would be fully defined in the MC layer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETSCHEDMODEL_H +#define LLVM_TARGET_TARGETSCHEDMODEL_H + +#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/MC/MCSchedule.h" +#include "llvm/MC/MCInstrItineraries.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +class TargetRegisterInfo; +class TargetSubtargetInfo; +class TargetInstrInfo; +class MachineInstr; + +/// Provide an instruction scheduling machine model to CodeGen passes. +class TargetSchedModel { + // For efficiency, hold a copy of the statically defined MCSchedModel for this + // processor. + MCSchedModel SchedModel; + InstrItineraryData InstrItins; + const TargetSubtargetInfo *STI; + const TargetInstrInfo *TII; + + SmallVector<unsigned, 16> ResourceFactors; + unsigned MicroOpFactor; // Multiply to normalize microops to resource units. + unsigned ResourceLCM; // Resource units per cycle. Latency normalization factor. +public: + TargetSchedModel(): STI(0), TII(0) {} + + /// \brief Initialize the machine model for instruction scheduling. + /// + /// The machine model API keeps a copy of the top-level MCSchedModel table + /// indices and may query TargetSubtargetInfo and TargetInstrInfo to resolve + /// dynamic properties. + void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti, + const TargetInstrInfo *tii); + + /// Return the MCSchedClassDesc for this instruction. + const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const; + + /// \brief TargetInstrInfo getter. + const TargetInstrInfo *getInstrInfo() const { return TII; } + + /// \brief Return true if this machine model includes an instruction-level + /// scheduling model. + /// + /// This is more detailed than the course grain IssueWidth and default + /// latency properties, but separate from the per-cycle itinerary data. + bool hasInstrSchedModel() const; + + const MCSchedModel *getMCSchedModel() const { return &SchedModel; } + + /// \brief Return true if this machine model includes cycle-to-cycle itinerary + /// data. + /// + /// This models scheduling at each stage in the processor pipeline. + bool hasInstrItineraries() const; + + const InstrItineraryData *getInstrItineraries() const { + if (hasInstrItineraries()) + return &InstrItins; + return 0; + } + + /// \brief Identify the processor corresponding to the current subtarget. + unsigned getProcessorID() const { return SchedModel.getProcessorID(); } + + /// \brief Maximum number of micro-ops that may be scheduled per cycle. + unsigned getIssueWidth() const { return SchedModel.IssueWidth; } + + /// \brief Return the number of issue slots required for this MI. + unsigned getNumMicroOps(const MachineInstr *MI, + const MCSchedClassDesc *SC = 0) const; + + /// \brief Get the number of kinds of resources for this target. + unsigned getNumProcResourceKinds() const { + return SchedModel.getNumProcResourceKinds(); + } + + /// \brief Get a processor resource by ID for convenience. + const MCProcResourceDesc *getProcResource(unsigned PIdx) const { + return SchedModel.getProcResource(PIdx); + } + + typedef const MCWriteProcResEntry *ProcResIter; + + // \brief Get an iterator into the processor resources consumed by this + // scheduling class. + ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const { + // The subtarget holds a single resource table for all processors. + return STI->getWriteProcResBegin(SC); + } + ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const { + return STI->getWriteProcResEnd(SC); + } + + /// \brief Multiply the number of units consumed for a resource by this factor + /// to normalize it relative to other resources. + unsigned getResourceFactor(unsigned ResIdx) const { + return ResourceFactors[ResIdx]; + } + + /// \brief Multiply number of micro-ops by this factor to normalize it + /// relative to other resources. + unsigned getMicroOpFactor() const { + return MicroOpFactor; + } + + /// \brief Multiply cycle count by this factor to normalize it relative to + /// other resources. This is the number of resource units per cycle. + unsigned getLatencyFactor() const { + return ResourceLCM; + } + + /// \brief Compute operand latency based on the available machine model. + /// + /// Computes and return the latency of the given data dependent def and use + /// when the operand indices are already known. UseMI may be NULL for an + /// unknown user. + /// + /// FindMin may be set to get the minimum vs. expected latency. Minimum + /// latency is used for scheduling groups, while expected latency is for + /// instruction cost and critical path. + unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, + const MachineInstr *UseMI, unsigned UseOperIdx, + bool FindMin) const; + + /// \brief Compute the instruction latency based on the available machine + /// model. + /// + /// Compute and return the expected latency of this instruction independent of + /// a particular use. computeOperandLatency is the prefered API, but this is + /// occasionally useful to help estimate instruction cost. + unsigned computeInstrLatency(const MachineInstr *MI) const; + + /// \brief Output dependency latency of a pair of defs of the same register. + /// + /// This is typically one cycle. + unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx, + const MachineInstr *DepMI) const; + +private: + /// getDefLatency is a helper for computeOperandLatency. Return the + /// instruction's latency if operand lookup is not required. + /// Otherwise return -1. + int getDefLatency(const MachineInstr *DefMI, bool FindMin) const; +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index eb38cd3..2401992 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -56,50 +56,56 @@ namespace llvm { FIRST_FP_VALUETYPE = f16, LAST_FP_VALUETYPE = ppcf128, - v2i8 = 13, // 2 x i8 - v4i8 = 14, // 4 x i8 - v8i8 = 15, // 8 x i8 - v16i8 = 16, // 16 x i8 - v32i8 = 17, // 32 x i8 - v2i16 = 18, // 2 x i16 - v4i16 = 19, // 4 x i16 - v8i16 = 20, // 8 x i16 - v16i16 = 21, // 16 x i16 - v2i32 = 22, // 2 x i32 - v4i32 = 23, // 4 x i32 - v8i32 = 24, // 8 x i32 - v16i32 = 25, // 16 x i32 - v1i64 = 26, // 1 x i64 - v2i64 = 27, // 2 x i64 - v4i64 = 28, // 4 x i64 - v8i64 = 29, // 8 x i64 - v16i64 = 30, // 16 x i64 - - v2f16 = 31, // 2 x f16 - v2f32 = 32, // 2 x f32 - v4f32 = 33, // 4 x f32 - v8f32 = 34, // 8 x f32 - v2f64 = 35, // 2 x f64 - v4f64 = 36, // 4 x f64 - - FIRST_VECTOR_VALUETYPE = v2i8, + v2i1 = 13, // 2 x i1 + v4i1 = 14, // 4 x i1 + v8i1 = 15, // 8 x i1 + v16i1 = 16, // 16 x i1 + v2i8 = 17, // 2 x i8 + v4i8 = 18, // 4 x i8 + v8i8 = 19, // 8 x i8 + v16i8 = 20, // 16 x i8 + v32i8 = 21, // 32 x i8 + v1i16 = 22, // 1 x i16 + v2i16 = 23, // 2 x i16 + v4i16 = 24, // 4 x i16 + v8i16 = 25, // 8 x i16 + v16i16 = 26, // 16 x i16 + v1i32 = 27, // 1 x i32 + v2i32 = 28, // 2 x i32 + v4i32 = 29, // 4 x i32 + v8i32 = 30, // 8 x i32 + v16i32 = 31, // 16 x i32 + v1i64 = 32, // 1 x i64 + v2i64 = 33, // 2 x i64 + v4i64 = 34, // 4 x i64 + v8i64 = 35, // 8 x i64 + v16i64 = 36, // 16 x i64 + + v2f16 = 37, // 2 x f16 + v2f32 = 38, // 2 x f32 + v4f32 = 39, // 4 x f32 + v8f32 = 40, // 8 x f32 + v2f64 = 41, // 2 x f64 + v4f64 = 42, // 4 x f64 + + FIRST_VECTOR_VALUETYPE = v2i1, LAST_VECTOR_VALUETYPE = v4f64, - FIRST_INTEGER_VECTOR_VALUETYPE = v2i8, + FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, LAST_INTEGER_VECTOR_VALUETYPE = v16i64, FIRST_FP_VECTOR_VALUETYPE = v2f16, LAST_FP_VECTOR_VALUETYPE = v4f64, - x86mmx = 37, // This is an X86 MMX value + x86mmx = 43, // This is an X86 MMX value - Glue = 38, // This glues nodes together during pre-RA sched + Glue = 44, // This glues nodes together during pre-RA sched - isVoid = 39, // This has no value + isVoid = 45, // This has no value - Untyped = 40, // This value takes a register, but has + Untyped = 46, // This value takes a register, but has // unspecified type. The register class // will be determined by the opcode. - LAST_VALUETYPE = 41, // This always remains at the end of the list. + LAST_VALUETYPE = 47, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors @@ -175,6 +181,18 @@ namespace llvm { SimpleTy <= MVT::LAST_VECTOR_VALUETYPE); } + /// is16BitVector - Return true if this is a 16-bit vector type. + bool is16BitVector() const { + return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 || + SimpleTy == MVT::v16i1); + } + + /// is32BitVector - Return true if this is a 32-bit vector type. + bool is32BitVector() const { + return (SimpleTy == MVT::v4i8 || SimpleTy == MVT::v2i16 || + SimpleTy == MVT::v1i32); + } + /// is64BitVector - Return true if this is a 64-bit vector type. bool is64BitVector() const { return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 || @@ -233,15 +251,21 @@ namespace llvm { switch (SimpleTy) { default: llvm_unreachable("Not a vector MVT!"); + case v2i1 : + case v4i1 : + case v8i1 : + case v16i1: return i1; case v2i8 : case v4i8 : case v8i8 : case v16i8: case v32i8: return i8; + case v1i16: case v2i16: case v4i16: case v8i16: case v16i16: return i16; + case v1i32: case v2i32: case v4i32: case v8i32: @@ -265,21 +289,25 @@ namespace llvm { default: llvm_unreachable("Not a vector MVT!"); case v32i8: return 32; + case v16i1: case v16i8: case v16i16: case v16i32: case v16i64:return 16; + case v8i1: case v8i8 : case v8i16: case v8i32: case v8i64: case v8f32: return 8; + case v4i1: case v4i8: case v4i16: case v4i32: case v4i64: case v4f32: case v4f64: return 4; + case v2i1: case v2i8: case v2i16: case v2i32: @@ -287,6 +315,8 @@ namespace llvm { case v2f16: case v2f32: case v2f64: return 2; + case v1i16: + case v1i32: case v1i64: return 1; } } @@ -302,15 +332,21 @@ namespace llvm { default: llvm_unreachable("getSizeInBits called on extended MVT."); case i1 : return 1; - case i8 : return 8; + case v2i1: return 2; + case v4i1: return 4; + case i8 : + case v8i1: return 8; case i16 : case f16: - case v2i8: return 16; + case v16i1: + case v2i8: + case v1i16: return 16; case f32 : case i32 : case v4i8: case v2i16: - case v2f16: return 32; + case v2f16: + case v1i32: return 32; case x86mmx: case f64 : case i64 : @@ -393,6 +429,12 @@ namespace llvm { switch (VT.SimpleTy) { default: break; + case MVT::i1: + if (NumElements == 2) return MVT::v2i1; + if (NumElements == 4) return MVT::v4i1; + if (NumElements == 8) return MVT::v8i1; + if (NumElements == 16) return MVT::v16i1; + break; case MVT::i8: if (NumElements == 2) return MVT::v2i8; if (NumElements == 4) return MVT::v4i8; @@ -401,12 +443,14 @@ namespace llvm { if (NumElements == 32) return MVT::v32i8; break; case MVT::i16: + if (NumElements == 1) return MVT::v1i16; if (NumElements == 2) return MVT::v2i16; if (NumElements == 4) return MVT::v4i16; if (NumElements == 8) return MVT::v8i16; if (NumElements == 16) return MVT::v16i16; break; case MVT::i32: + if (NumElements == 1) return MVT::v1i32; if (NumElements == 2) return MVT::v2i32; if (NumElements == 4) return MVT::v4i32; if (NumElements == 8) return MVT::v8i32; @@ -529,6 +573,16 @@ namespace llvm { return isSimple() ? V.isVector() : isExtendedVector(); } + /// is16BitVector - Return true if this is a 16-bit vector type. + bool is16BitVector() const { + return isSimple() ? V.is16BitVector() : isExtended16BitVector(); + } + + /// is32BitVector - Return true if this is a 32-bit vector type. + bool is32BitVector() const { + return isSimple() ? V.is32BitVector() : isExtended32BitVector(); + } + /// is64BitVector - Return true if this is a 64-bit vector type. bool is64BitVector() const { return isSimple() ? V.is64BitVector() : isExtended64BitVector(); @@ -740,6 +794,8 @@ namespace llvm { bool isExtendedFloatingPoint() const; bool isExtendedInteger() const; bool isExtendedVector() const; + bool isExtended16BitVector() const; + bool isExtended32BitVector() const; bool isExtended64BitVector() const; bool isExtended128BitVector() const; bool isExtended256BitVector() const; diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index f4b75bd..a707f88 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -33,36 +33,42 @@ def f80 : ValueType<80 , 10>; // 80-bit floating point value def f128 : ValueType<128, 11>; // 128-bit floating point value def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value -def v2i8 : ValueType<16 , 13>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 14>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 15>; // 8 x i8 vector value -def v16i8 : ValueType<128, 16>; // 16 x i8 vector value -def v32i8 : ValueType<256, 17>; // 32 x i8 vector value -def v2i16 : ValueType<32 , 18>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 19>; // 4 x i16 vector value -def v8i16 : ValueType<128, 20>; // 8 x i16 vector value -def v16i16 : ValueType<256, 21>; // 16 x i16 vector value -def v2i32 : ValueType<64 , 22>; // 2 x i32 vector value -def v4i32 : ValueType<128, 23>; // 4 x i32 vector value -def v8i32 : ValueType<256, 24>; // 8 x i32 vector value -def v16i32 : ValueType<512, 25>; // 16 x i32 vector value -def v1i64 : ValueType<64 , 26>; // 1 x i64 vector value -def v2i64 : ValueType<128, 27>; // 2 x i64 vector value -def v4i64 : ValueType<256, 28>; // 4 x i64 vector value -def v8i64 : ValueType<512, 29>; // 8 x i64 vector value -def v16i64 : ValueType<1024,30>; // 16 x i64 vector value +def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value +def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value +def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value +def v16i1 : ValueType<16, 16>; // 16 x i1 vector value +def v2i8 : ValueType<16 , 17>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 18>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 19>; // 8 x i8 vector value +def v16i8 : ValueType<128, 20>; // 16 x i8 vector value +def v32i8 : ValueType<256, 21>; // 32 x i8 vector value +def v1i16 : ValueType<16 , 22>; // 1 x i16 vector value +def v2i16 : ValueType<32 , 23>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 24>; // 4 x i16 vector value +def v8i16 : ValueType<128, 25>; // 8 x i16 vector value +def v16i16 : ValueType<256, 26>; // 16 x i16 vector value +def v1i32 : ValueType<32 , 27>; // 1 x i32 vector value +def v2i32 : ValueType<64 , 28>; // 2 x i32 vector value +def v4i32 : ValueType<128, 29>; // 4 x i32 vector value +def v8i32 : ValueType<256, 30>; // 8 x i32 vector value +def v16i32 : ValueType<512, 31>; // 16 x i32 vector value +def v1i64 : ValueType<64 , 32>; // 1 x i64 vector value +def v2i64 : ValueType<128, 33>; // 2 x i64 vector value +def v4i64 : ValueType<256, 34>; // 4 x i64 vector value +def v8i64 : ValueType<512, 35>; // 8 x i64 vector value +def v16i64 : ValueType<1024,36>; // 16 x i64 vector value -def v2f16 : ValueType<32 , 31>; // 2 x f16 vector value -def v2f32 : ValueType<64 , 32>; // 2 x f32 vector value -def v4f32 : ValueType<128, 33>; // 4 x f32 vector value -def v8f32 : ValueType<256, 34>; // 8 x f32 vector value -def v2f64 : ValueType<128, 35>; // 2 x f64 vector value -def v4f64 : ValueType<256, 36>; // 4 x f64 vector value +def v2f16 : ValueType<32 , 37>; // 2 x f16 vector value +def v2f32 : ValueType<64 , 38>; // 2 x f32 vector value +def v4f32 : ValueType<128, 39>; // 4 x f32 vector value +def v8f32 : ValueType<256, 40>; // 8 x f32 vector value +def v2f64 : ValueType<128, 41>; // 2 x f64 vector value +def v4f64 : ValueType<256, 42>; // 4 x f64 vector value -def x86mmx : ValueType<64 , 37>; // X86 MMX value -def FlagVT : ValueType<0 , 38>; // Pre-RA sched glue -def isVoid : ValueType<0 , 39>; // Produces no value -def untyped: ValueType<8 , 40>; // Produces an untyped value +def x86mmx : ValueType<64 , 43>; // X86 MMX value +def FlagVT : ValueType<0 , 44>; // Pre-RA sched glue +def isVoid : ValueType<0 , 45>; // Produces no value +def untyped: ValueType<8 , 46>; // Produces an untyped value def MetadataVT: ValueType<0, 250>; // Metadata diff --git a/include/llvm/Config/AsmParsers.def.in b/include/llvm/Config/AsmParsers.def.in index 041af83..d636753 100644 --- a/include/llvm/Config/AsmParsers.def.in +++ b/include/llvm/Config/AsmParsers.def.in @@ -1,24 +1,24 @@ -//===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file enumerates all of the assembly-language parsers -// supported by this build of LLVM. Clients of this file should define -// the LLVM_ASM_PARSER macro to be a function-like macro with a -// single parameter (the name of the target whose assembly can be -// generated); including this file will then enumerate all of the -// targets with assembly parsers. -// -// The set of targets supported by LLVM is generated at configuration -// time, at which point this header is generated. Do not modify this -// header directly. -// -//===----------------------------------------------------------------------===// +/*===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file enumerates all of the assembly-language parsers *| +|* supported by this build of LLVM. Clients of this file should define *| +|* the LLVM_ASM_PARSER macro to be a function-like macro with a *| +|* single parameter (the name of the target whose assembly can be *| +|* generated); including this file will then enumerate all of the *| +|* targets with assembly parsers. *| +|* *| +|* The set of targets supported by LLVM is generated at configuration *| +|* time, at which point this header is generated. Do not modify this *| +|* header directly. *| +|* *| +\*===----------------------------------------------------------------------===*/ #ifndef LLVM_ASM_PARSER # error Please define the macro LLVM_ASM_PARSER(TargetName) diff --git a/include/llvm/Config/AsmPrinters.def.in b/include/llvm/Config/AsmPrinters.def.in index 9729bd7..f0152a4 100644 --- a/include/llvm/Config/AsmPrinters.def.in +++ b/include/llvm/Config/AsmPrinters.def.in @@ -1,24 +1,24 @@ -//===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file enumerates all of the assembly-language printers -// supported by this build of LLVM. Clients of this file should define -// the LLVM_ASM_PRINTER macro to be a function-like macro with a -// single parameter (the name of the target whose assembly can be -// generated); including this file will then enumerate all of the -// targets with assembly printers. -// -// The set of targets supported by LLVM is generated at configuration -// time, at which point this header is generated. Do not modify this -// header directly. -// -//===----------------------------------------------------------------------===// +/*===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file enumerates all of the assembly-language printers *| +|* supported by this build of LLVM. Clients of this file should define *| +|* the LLVM_ASM_PRINTER macro to be a function-like macro with a *| +|* single parameter (the name of the target whose assembly can be *| +|* generated); including this file will then enumerate all of the *| +|* targets with assembly printers. *| +|* *| +|* The set of targets supported by LLVM is generated at configuration *| +|* time, at which point this header is generated. Do not modify this *| +|* header directly. *| +|* *| +\*===----------------------------------------------------------------------===*/ #ifndef LLVM_ASM_PRINTER # error Please define the macro LLVM_ASM_PRINTER(TargetName) diff --git a/include/llvm/Config/Disassemblers.def.in b/include/llvm/Config/Disassemblers.def.in index 1e6281d..d3a9bbd 100644 --- a/include/llvm/Config/Disassemblers.def.in +++ b/include/llvm/Config/Disassemblers.def.in @@ -1,24 +1,24 @@ -//===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file enumerates all of the assembly-language parsers -// supported by this build of LLVM. Clients of this file should define -// the LLVM_DISASSEMBLER macro to be a function-like macro with a -// single parameter (the name of the target whose assembly can be -// generated); including this file will then enumerate all of the -// targets with assembly parsers. -// -// The set of targets supported by LLVM is generated at configuration -// time, at which point this header is generated. Do not modify this -// header directly. -// -//===----------------------------------------------------------------------===// +/*===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file enumerates all of the assembly-language parsers *| +|* supported by this build of LLVM. Clients of this file should define *| +|* the LLVM_DISASSEMBLER macro to be a function-like macro with a *| +|* single parameter (the name of the target whose assembly can be *| +|* generated); including this file will then enumerate all of the *| +|* targets with assembly parsers. *| +|* *| +|* The set of targets supported by LLVM is generated at configuration *| +|* time, at which point this header is generated. Do not modify this *| +|* header directly. *| +|* *| +\*===----------------------------------------------------------------------===*/ #ifndef LLVM_DISASSEMBLER # error Please define the macro LLVM_DISASSEMBLER(TargetName) diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index b912251..ca64124 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -1,6 +1,4 @@ -/************************************** -** Created by Kevin from config.h.in ** -***************************************/ +/* include/llvm/Config/config.h.cmake corresponding to config.h.in. */ #ifndef CONFIG_H #define CONFIG_H @@ -17,6 +15,9 @@ /* Default <path> to all compiler invocations for --sysroot=<path>. */ #undef DEFAULT_SYSROOT +/* Define if you want backtraces on crash */ +#cmakedefine ENABLE_BACKTRACES + /* Define if position independent code is enabled */ #cmakedefine ENABLE_PIC @@ -51,7 +52,7 @@ #cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H} /* Define to 1 if you have the `backtrace' function. */ -#undef HAVE_BACKTRACE +#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE} /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 5a60ba5..a4f8af4 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -18,6 +18,9 @@ /* Default <path> to all compiler invocations for --sysroot=<path>. */ #undef DEFAULT_SYSROOT +/* Define if you want backtraces on crash */ +#undef ENABLE_BACKTRACES + /* Define if position independent code is enabled */ #undef ENABLE_PIC diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index e0e516d..0ddd1db 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -39,8 +39,8 @@ namespace llvm { /// don't have to worry about the lifetime of the objects. /// @brief LLVM Constant Representation class Constant : public User { - void operator=(const Constant &); // Do not implement - Constant(const Constant &); // Do not implement + void operator=(const Constant &) LLVM_DELETED_FUNCTION; + Constant(const Constant &) LLVM_DELETED_FUNCTION; virtual void anchor(); protected: @@ -65,6 +65,9 @@ public: /// true for things like constant expressions that could divide by zero. bool canTrap() const; + /// isThreadDependent - Return true if the value can vary between threads. + bool isThreadDependent() const; + /// isConstantUsed - Return true if the constant has users other than constant /// exprs and other dangling things. bool isConstantUsed() const; @@ -108,8 +111,6 @@ public: virtual void destroyConstant() { llvm_unreachable("Not reached!"); } //// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Constant *) { return true; } - static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() >= ConstantFirstVal && V->getValueID() <= ConstantLastVal; diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index fdd5382..7f94ef4 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -49,8 +49,8 @@ struct ConvertConstantType; /// @brief Class for constant integers. class ConstantInt : public Constant { virtual void anchor(); - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION; ConstantInt(IntegerType *Ty, const APInt& V); APInt Val; protected: @@ -221,7 +221,6 @@ public: } /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const ConstantInt *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantIntVal; } @@ -234,8 +233,8 @@ public: class ConstantFP : public Constant { APFloat Val; virtual void anchor(); - void *operator new(size_t, unsigned);// DO NOT IMPLEMENT - ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION; friend class LLVMContextImpl; protected: ConstantFP(Type *Ty, const APFloat& V); @@ -283,15 +282,11 @@ public: bool isExactlyValue(double V) const { bool ignored; - // convert is not supported on this type - if (&Val.getSemantics() == &APFloat::PPCDoubleDouble) - return false; APFloat FV(V); FV.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &ignored); return isExactlyValue(FV); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantFP *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantFPVal; } @@ -301,8 +296,8 @@ public: /// ConstantAggregateZero - All zero aggregate value /// class ConstantAggregateZero : public Constant { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantAggregateZero(const ConstantAggregateZero &) LLVM_DELETED_FUNCTION; protected: explicit ConstantAggregateZero(Type *ty) : Constant(ty, ConstantAggregateZeroVal, 0, 0) {} @@ -334,7 +329,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantAggregateZero *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantAggregateZeroVal; } @@ -346,7 +340,7 @@ public: /// class ConstantArray : public Constant { friend struct ConstantArrayCreator<ConstantArray, ArrayType>; - ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT + ConstantArray(const ConstantArray &) LLVM_DELETED_FUNCTION; protected: ConstantArray(ArrayType *T, ArrayRef<Constant *> Val); public: @@ -367,7 +361,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantArray *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantArrayVal; } @@ -385,7 +378,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant) // class ConstantStruct : public Constant { friend struct ConstantArrayCreator<ConstantStruct, StructType>; - ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT + ConstantStruct(const ConstantStruct &) LLVM_DELETED_FUNCTION; protected: ConstantStruct(StructType *T, ArrayRef<Constant *> Val); public: @@ -426,7 +419,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantStruct *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantStructVal; } @@ -445,7 +437,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant) /// class ConstantVector : public Constant { friend struct ConstantArrayCreator<ConstantVector, VectorType>; - ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT + ConstantVector(const ConstantVector &) LLVM_DELETED_FUNCTION; protected: ConstantVector(VectorType *T, ArrayRef<Constant *> Val); public: @@ -474,7 +466,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantVector *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantVectorVal; } @@ -491,8 +482,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant) /// ConstantPointerNull - a constant pointer value that points to null /// class ConstantPointerNull : public Constant { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantPointerNull(const ConstantPointerNull &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION; protected: explicit ConstantPointerNull(PointerType *T) : Constant(reinterpret_cast<Type*>(T), @@ -517,7 +508,6 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantPointerNull *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantPointerNullVal; } @@ -543,8 +533,8 @@ class ConstantDataSequential : public Constant { /// element array of i8, or a 1-element array of i32. They'll both end up in /// the same StringMap bucket, linked up. ConstantDataSequential *Next; - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantDataSequential(const ConstantDataSequential &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantDataSequential(const ConstantDataSequential &) LLVM_DELETED_FUNCTION; protected: explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data) : Constant(ty, VT, 0, 0), DataElements(Data), Next(0) {} @@ -639,7 +629,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataSequential *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataArrayVal || V->getValueID() == ConstantDataVectorVal; @@ -655,8 +644,8 @@ private: /// operands because it stores all of the elements of the constant as densely /// packed data, instead of as Value*'s. class ConstantDataArray : public ConstantDataSequential { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantDataArray(const ConstantDataArray &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION; virtual void anchor(); friend class ConstantDataSequential; explicit ConstantDataArray(Type *ty, const char *Data) @@ -695,7 +684,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataArray *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataArrayVal; } @@ -708,8 +696,8 @@ public: /// operands because it stores all of the elements of the constant as densely /// packed data, instead of as Value*'s. class ConstantDataVector : public ConstantDataSequential { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - ConstantDataVector(const ConstantDataVector &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION; virtual void anchor(); friend class ConstantDataSequential; explicit ConstantDataVector(Type *ty, const char *Data) @@ -749,7 +737,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataVector *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataVectorVal; } @@ -760,7 +747,7 @@ public: /// BlockAddress - The address of a basic block. /// class BlockAddress : public Constant { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void *operator new(size_t s) { return User::operator new(s, 2); } BlockAddress(Function *F, BasicBlock *BB); public: @@ -781,7 +768,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BlockAddress *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == BlockAddressVal; } @@ -1094,7 +1080,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantExpr *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; } @@ -1125,8 +1110,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant) /// LangRef.html#undefvalues for details. /// class UndefValue : public Constant { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - UndefValue(const UndefValue &); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + UndefValue(const UndefValue &) LLVM_DELETED_FUNCTION; protected: explicit UndefValue(Type *T) : Constant(T, UndefValueVal, 0, 0) {} protected: @@ -1159,7 +1144,6 @@ public: virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UndefValue *) { return true; } static bool classof(const Value *V) { return V->getValueID() == UndefValueVal; } diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h index 2ed48a9..2f07800 100644 --- a/include/llvm/DIBuilder.h +++ b/include/llvm/DIBuilder.h @@ -63,8 +63,8 @@ namespace llvm { SmallVector<Value *, 4> AllSubprograms; SmallVector<Value *, 4> AllGVs; - DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT - void operator=(const DIBuilder &); // DO NOT IMPLEMENT + DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION; + void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION; public: explicit DIBuilder(Module &M); @@ -179,8 +179,10 @@ namespace llvm { /// @param Ty Parent type. /// @param PropertyName Name of the Objective C property associated with /// this ivar. - /// @param GetterName Name of the Objective C property getter selector. - /// @param SetterName Name of the Objective C property setter selector. + /// @param PropertyGetterName Name of the Objective C property getter + /// selector. + /// @param PropertySetterName Name of the Objective C property setter + /// selector. /// @param PropertyAttributes Objective C property attributes. DIType createObjCIVar(StringRef Name, DIFile File, unsigned LineNo, uint64_t SizeInBits, @@ -201,7 +203,7 @@ namespace llvm { /// @param OffsetInBits Member offset. /// @param Flags Flags to encode member attribute, e.g. private /// @param Ty Parent type. - /// @param Property Property associated with this ivar. + /// @param PropertyNode Property associated with this ivar. DIType createObjCIVar(StringRef Name, DIFile File, unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, @@ -228,7 +230,7 @@ namespace llvm { /// @param Scope Scope in which this class is defined. /// @param Name class name. /// @param File File where this member is defined. - /// @param LineNo Line number. + /// @param LineNumber Line number. /// @param SizeInBits Member size. /// @param AlignInBits Member alignment. /// @param OffsetInBits Member offset. @@ -250,7 +252,7 @@ namespace llvm { /// @param Scope Scope in which this struct is defined. /// @param Name Struct name. /// @param File File where this member is defined. - /// @param LineNo Line number. + /// @param LineNumber Line number. /// @param SizeInBits Member size. /// @param AlignInBits Member alignment. /// @param Flags Flags to encode member attribute, e.g. private @@ -265,7 +267,7 @@ namespace llvm { /// @param Scope Scope in which this union is defined. /// @param Name Union name. /// @param File File where this member is defined. - /// @param LineNo Line number. + /// @param LineNumber Line number. /// @param SizeInBits Member size. /// @param AlignInBits Member alignment. /// @param Flags Flags to encode member attribute, e.g. private @@ -325,33 +327,36 @@ namespace llvm { /// @param Scope Scope in which this enumeration is defined. /// @param Name Union name. /// @param File File where this member is defined. - /// @param LineNo Line number. + /// @param LineNumber Line number. /// @param SizeInBits Member size. /// @param AlignInBits Member alignment. /// @param Elements Enumeration elements. - /// @param Flags Flags (e.g. forward decl) DIType createEnumerationType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - DIArray Elements, DIType ClassType, - unsigned Flags); + DIArray Elements, DIType ClassType); /// createSubroutineType - Create subroutine type. - /// @param File File in which this subroutine is defined. - /// @param ParamterTypes An array of subroutine parameter types. This - /// includes return type at 0th index. + /// @param File File in which this subroutine is defined. + /// @param ParameterTypes An array of subroutine parameter types. This + /// includes return type at 0th index. DIType createSubroutineType(DIFile File, DIArray ParameterTypes); /// createArtificialType - Create a new DIType with "artificial" flag set. DIType createArtificialType(DIType Ty); + /// createObjectPointerType - Create a new DIType with the "object pointer" + /// flag set. + DIType createObjectPointerType(DIType Ty); + /// createTemporaryType - Create a temporary forward-declared type. DIType createTemporaryType(); DIType createTemporaryType(DIFile F); /// createForwardDecl - Create a temporary forward-declared type. DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, - DIFile F, unsigned Line, unsigned RuntimeLang = 0); + DIFile F, unsigned Line, unsigned RuntimeLang = 0, + uint64_t SizeInBits = 0, uint64_t AlignInBits = 0); /// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. @@ -383,9 +388,9 @@ namespace llvm { /// createStaticVariable - Create a new descriptor for the specified /// variable. - /// @param Conext Variable scope. + /// @param Context Variable scope. /// @param Name Name of the variable. - /// @param LinakgeName Mangled name of the variable. + /// @param LinkageName Mangled name of the variable. /// @param File File where this variable is defined. /// @param LineNo Line number. /// @param Ty Variable Type. @@ -426,7 +431,7 @@ namespace llvm { /// DW_TAG_arg_variable. /// @param Scope Variable scope. /// @param Name Variable name. - /// @param File File where this variable is defined. + /// @param F File where this variable is defined. /// @param LineNo Line number. /// @param Ty Variable Type /// @param Addr An array of complex address operations. diff --git a/include/llvm/Target/TargetData.h b/include/llvm/DataLayout.h index 4f94ab7..24ad05f 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/DataLayout.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===// +//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines target properties related to datatype size/offset/alignment +// This file defines layout properties related to datatype size/offset/alignment // information. It uses lazy annotations to cache information about how // structure types are laid out and used. // @@ -17,11 +17,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETDATA_H -#define LLVM_TARGET_TARGETDATA_H +#ifndef LLVM_DATALAYOUT_H +#define LLVM_DATALAYOUT_H #include "llvm/Pass.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -36,7 +37,7 @@ class LLVMContext; template<typename T> class ArrayRef; -/// Enum used to categorize the alignment types stored by TargetAlignElem +/// Enum used to categorize the alignment types stored by LayoutAlignElem enum AlignTypeEnum { INTEGER_ALIGN = 'i', ///< Integer type alignment VECTOR_ALIGN = 'v', ///< Vector type alignment @@ -45,38 +46,55 @@ enum AlignTypeEnum { STACK_ALIGN = 's' ///< Stack objects alignment }; -/// Target alignment element. +/// Layout alignment element. /// -/// Stores the alignment data associated with a given alignment type (pointer, -/// integer, vector, float) and type bit width. +/// Stores the alignment data associated with a given alignment type (integer, +/// vector, float) and type bit width. /// /// @note The unusual order of elements in the structure attempts to reduce /// padding and make the structure slightly more cache friendly. -struct TargetAlignElem { - AlignTypeEnum AlignType : 8; ///< Alignment type (AlignTypeEnum) +struct LayoutAlignElem { + unsigned AlignType : 8; ///< Alignment type (AlignTypeEnum) + unsigned TypeBitWidth : 24; ///< Type bit width + unsigned ABIAlign : 16; ///< ABI alignment for this type/bitw + unsigned PrefAlign : 16; ///< Pref. alignment for this type/bitw + + /// Initializer + static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align, + unsigned pref_align, uint32_t bit_width); + /// Equality predicate + bool operator==(const LayoutAlignElem &rhs) const; +}; + +/// Layout pointer alignment element. +/// +/// Stores the alignment data associated with a given pointer and address space. +/// +/// @note The unusual order of elements in the structure attempts to reduce +/// padding and make the structure slightly more cache friendly. +struct PointerAlignElem { unsigned ABIAlign; ///< ABI alignment for this type/bitw unsigned PrefAlign; ///< Pref. alignment for this type/bitw uint32_t TypeBitWidth; ///< Type bit width + uint32_t AddressSpace; ///< Address space for the pointer type /// Initializer - static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align, + static PointerAlignElem get(uint32_t addr_space, unsigned abi_align, unsigned pref_align, uint32_t bit_width); /// Equality predicate - bool operator==(const TargetAlignElem &rhs) const; + bool operator==(const PointerAlignElem &rhs) const; }; -/// TargetData - This class holds a parsed version of the target data layout + +/// DataLayout - This class holds a parsed version of the target data layout /// string in a module and provides methods for querying it. The target data /// layout string is specified *by the target* - a frontend generating LLVM IR /// is required to generate the right target data for the target being codegen'd /// to. If some measure of portability is desired, an empty string may be /// specified in the module. -class TargetData : public ImmutablePass { +class DataLayout : public ImmutablePass { private: bool LittleEndian; ///< Defaults to false - unsigned PointerMemSize; ///< Pointer size in bytes - unsigned PointerABIAlign; ///< Pointer ABI alignment - unsigned PointerPrefAlign; ///< Pointer preferred alignment unsigned StackNaturalAlign; ///< Stack natural alignment SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. @@ -85,13 +103,18 @@ private: /// /// @sa init(). /// @note Could support multiple size pointer alignments, e.g., 32-bit - /// pointers vs. 64-bit pointers by extending TargetAlignment, but for now, + /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now, /// we don't. - SmallVector<TargetAlignElem, 16> Alignments; + SmallVector<LayoutAlignElem, 16> Alignments; + DenseMap<unsigned, PointerAlignElem> Pointers; /// InvalidAlignmentElem - This member is a signal that a requested alignment /// type and bit width were not found in the SmallVector. - static const TargetAlignElem InvalidAlignmentElem; + static const LayoutAlignElem InvalidAlignmentElem; + + /// InvalidPointerElem - This member is a signal that a requested pointer + /// type and bit width were not found in the DenseSet. + static const PointerAlignElem InvalidPointerElem; // The StructType -> StructLayout map. mutable void *LayoutMap; @@ -101,18 +124,31 @@ private: unsigned pref_align, uint32_t bit_width); unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, bool ABIAlign, Type *Ty) const; + + //! Set/initialize pointer alignments + void setPointerAlignment(uint32_t addr_space, unsigned abi_align, + unsigned pref_align, uint32_t bit_width); + //! Internal helper method that returns requested alignment for type. unsigned getAlignment(Type *Ty, bool abi_or_pref) const; /// Valid alignment predicate. /// - /// Predicate that tests a TargetAlignElem reference returned by get() against + /// Predicate that tests a LayoutAlignElem reference returned by get() against /// InvalidAlignmentElem. - bool validAlignment(const TargetAlignElem &align) const { + bool validAlignment(const LayoutAlignElem &align) const { return &align != &InvalidAlignmentElem; } - /// Initialise a TargetData object with default values, ensure that the + /// Valid pointer predicate. + /// + /// Predicate that tests a PointerAlignElem reference returned by get() against + /// InvalidPointerElem. + bool validPointer(const PointerAlignElem &align) const { + return &align != &InvalidPointerElem; + } + + /// Initialise a DataLayout object with default values, ensure that the /// target data pass is registered. void init(); @@ -121,43 +157,42 @@ public: /// /// @note This has to exist, because this is a pass, but it should never be /// used. - TargetData(); + DataLayout(); - /// Constructs a TargetData from a specification string. See init(). - explicit TargetData(StringRef TargetDescription) + /// Constructs a DataLayout from a specification string. See init(). + explicit DataLayout(StringRef LayoutDescription) : ImmutablePass(ID) { - std::string errMsg = parseSpecifier(TargetDescription, this); + std::string errMsg = parseSpecifier(LayoutDescription, this); assert(errMsg == "" && "Invalid target data layout string."); (void)errMsg; } /// Parses a target data specification string. Returns an error message /// if the string is malformed, or the empty string on success. Optionally - /// initialises a TargetData object if passed a non-null pointer. - static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0); + /// initialises a DataLayout object if passed a non-null pointer. + static std::string parseSpecifier(StringRef LayoutDescription, + DataLayout* td = 0); /// Initialize target data from properties stored in the module. - explicit TargetData(const Module *M); + explicit DataLayout(const Module *M); - TargetData(const TargetData &TD) : + DataLayout(const DataLayout &TD) : ImmutablePass(ID), LittleEndian(TD.isLittleEndian()), - PointerMemSize(TD.PointerMemSize), - PointerABIAlign(TD.PointerABIAlign), - PointerPrefAlign(TD.PointerPrefAlign), LegalIntWidths(TD.LegalIntWidths), Alignments(TD.Alignments), + Pointers(TD.Pointers), LayoutMap(0) { } - ~TargetData(); // Not virtual, do not subclass this class + ~DataLayout(); // Not virtual, do not subclass this class - /// Target endianness... + /// Layout endianness... bool isLittleEndian() const { return LittleEndian; } bool isBigEndian() const { return !LittleEndian; } /// getStringRepresentation - Return the string representation of the - /// TargetData. This representation is in the same format accepted by the + /// DataLayout. This representation is in the same format accepted by the /// string constructor above. std::string getStringRepresentation() const; @@ -195,15 +230,42 @@ public: return false; } - /// Target pointer alignment - unsigned getPointerABIAlignment() const { return PointerABIAlign; } + /// Layout pointer alignment + /// FIXME: The defaults need to be removed once all of + /// the backends/clients are updated. + unsigned getPointerABIAlignment(unsigned AS = 0) const { + DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); + if (val == Pointers.end()) { + val = Pointers.find(0); + } + return val->second.ABIAlign; + } /// Return target's alignment for stack-based pointers - unsigned getPointerPrefAlignment() const { return PointerPrefAlign; } - /// Target pointer size - unsigned getPointerSize() const { return PointerMemSize; } - /// Target pointer size, in bits - unsigned getPointerSizeInBits() const { return 8*PointerMemSize; } - + /// FIXME: The defaults need to be removed once all of + /// the backends/clients are updated. + unsigned getPointerPrefAlignment(unsigned AS = 0) const { + DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); + if (val == Pointers.end()) { + val = Pointers.find(0); + } + return val->second.PrefAlign; + } + /// Layout pointer size + /// FIXME: The defaults need to be removed once all of + /// the backends/clients are updated. + unsigned getPointerSize(unsigned AS = 0) const { + DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); + if (val == Pointers.end()) { + val = Pointers.find(0); + } + return val->second.TypeBitWidth; + } + /// Layout pointer size, in bits + /// FIXME: The defaults need to be removed once all of + /// the backends/clients are updated. + unsigned getPointerSizeInBits(unsigned AS = 0) const { + return getPointerSize(AS) * 8; + } /// Size examples: /// /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*] @@ -279,10 +341,14 @@ public: /// unsigned getPreferredTypeAlignmentShift(Type *Ty) const; - /// getIntPtrType - Return an unsigned integer type that is the same size or - /// greater to the host pointer size. - /// - IntegerType *getIntPtrType(LLVMContext &C) const; + /// getIntPtrType - Return an integer type with size at least as big as that + /// of a pointer in the given address space. + IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const; + + /// getIntPtrType - Return an integer (vector of integer) type with size at + /// least as big as that of a pointer of the given pointer (vector of pointer) + /// type. + Type *getIntPtrType(Type *) const; /// getIndexedOffset - return the offset from the beginning of the type for /// the specified indices. This is used to implement getelementptr. @@ -318,7 +384,7 @@ public: }; /// StructLayout - used to lazily calculate structure layout information for a -/// target machine, based on the TargetData structure. +/// target machine, based on the DataLayout structure. /// class StructLayout { uint64_t StructSize; @@ -354,8 +420,8 @@ public: } private: - friend class TargetData; // Only TargetData can create this class - StructLayout(StructType *ST, const TargetData &TD); + friend class DataLayout; // Only DataLayout can create this class + StructLayout(StructType *ST, const DataLayout &TD); }; } // End llvm namespace diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h index 618220f..dae03ad 100644 --- a/include/llvm/DebugInfo.h +++ b/include/llvm/DebugInfo.h @@ -60,7 +60,8 @@ namespace llvm { FlagArtificial = 1 << 6, FlagExplicit = 1 << 7, FlagPrototyped = 1 << 8, - FlagObjcClassComplete = 1 << 9 + FlagObjcClassComplete = 1 << 9, + FlagObjectPointer = 1 << 10 }; protected: const MDNode *DbgNode; @@ -80,6 +81,7 @@ namespace llvm { GlobalVariable *getGlobalVariableField(unsigned Elt) const; Constant *getConstantField(unsigned Elt) const; Function *getFunctionField(unsigned Elt) const; + void replaceFunctionField(unsigned Elt, Function *F); public: explicit DIDescriptor() : DbgNode(0) {} @@ -287,6 +289,9 @@ namespace llvm { bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; } + bool isObjectPointer() const { + return (getFlags() & FlagObjectPointer) != 0; + } bool isObjcClassComplete() const { return (getFlags() & FlagObjcClassComplete) != 0; } @@ -558,6 +563,7 @@ namespace llvm { bool describes(const Function *F); Function *getFunction() const { return getFunctionField(16); } + void replaceFunction(Function *F) { replaceFunctionField(16, F); } DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); } DISubprogram getFunctionDeclaration() const { return getFieldAs<DISubprogram>(18); @@ -644,6 +650,10 @@ namespace llvm { return (getUnsignedField(6) & FlagArtificial) != 0; } + bool isObjectPointer() const { + return (getUnsignedField(6) & FlagObjectPointer) != 0; + } + /// getInlinedAt - If this variable is inlined then return inline location. MDNode *getInlinedAt() const; diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index cfdeb46..26bd1f6 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -15,6 +15,8 @@ #ifndef LLVM_DEBUGINFO_DICONTEXT_H #define LLVM_DEBUGINFO_DICONTEXT_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -54,6 +56,23 @@ public: } }; +/// DIInliningInfo - a format-neutral container for inlined code description. +class DIInliningInfo { + SmallVector<DILineInfo, 4> Frames; + public: + DIInliningInfo() {} + DILineInfo getFrame(unsigned Index) const { + assert(Index < Frames.size()); + return Frames[Index]; + } + uint32_t getNumberOfFrames() const { + return Frames.size(); + } + void addFrame(const DILineInfo &Frame) { + Frames.push_back(Frame); + } +}; + /// DILineInfoSpecifier - controls which fields of DILineInfo container /// should be filled with data. class DILineInfoSpecifier { @@ -71,6 +90,13 @@ public: } }; +// In place of applying the relocations to the data we've read from disk we use +// a separate mapping table to the side and checking that at locations in the +// dwarf where we expect relocated values. This adds a bit of complexity to the +// dwarf parsing/extraction at the benefit of not allocating memory for the +// entire size of the debug info sections. +typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; + class DIContext { public: virtual ~DIContext(); @@ -81,12 +107,16 @@ public: StringRef abbrevSection, StringRef aRangeSection = StringRef(), StringRef lineSection = StringRef(), - StringRef stringSection = StringRef()); + StringRef stringSection = StringRef(), + StringRef rangeSection = StringRef(), + const RelocAddrMap &Map = RelocAddrMap()); virtual void dump(raw_ostream &OS) = 0; - virtual DILineInfo getLineInfoForAddress(uint64_t address, - DILineInfoSpecifier specifier = DILineInfoSpecifier()) = 0; + virtual DILineInfo getLineInfoForAddress(uint64_t Address, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; + virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, + DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; }; } diff --git a/include/llvm/DefaultPasses.h b/include/llvm/DefaultPasses.h index 929569d..9f1ade8 100644 --- a/include/llvm/DefaultPasses.h +++ b/include/llvm/DefaultPasses.h @@ -14,7 +14,7 @@ #ifndef LLVM_DEFAULT_PASS_SUPPORT_H #define LLVM_DEFAULT_PASS_SUPPORT_H -#include <llvm/PassSupport.h> +#include "llvm/PassSupport.h" namespace llvm { diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index da5ad27..c862c2c 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -20,6 +20,7 @@ #include "llvm/Type.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Compiler.h" namespace llvm { @@ -84,7 +85,6 @@ public: bool isPowerOf2ByteWidth() const; // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const IntegerType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == IntegerTyID; } @@ -94,8 +94,8 @@ public: /// FunctionType - Class to represent function types /// class FunctionType : public Type { - FunctionType(const FunctionType &); // Do not implement - const FunctionType &operator=(const FunctionType &); // Do not implement + FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION; + const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION; FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs); public: @@ -133,7 +133,6 @@ public: unsigned getNumParams() const { return NumContainedTys - 1; } // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const FunctionType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == FunctionTyID; } @@ -156,7 +155,6 @@ public: bool indexValid(unsigned Idx) const; // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const CompositeType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || @@ -183,12 +181,12 @@ public: /// Independent of what kind of struct you have, the body of a struct type are /// laid out in memory consequtively with the elements directly one after the /// other (if the struct is packed) or (if not packed) with padding between the -/// elements as defined by TargetData (which is required to match what the code +/// elements as defined by DataLayout (which is required to match what the code /// generator for a target expects). /// class StructType : public CompositeType { - StructType(const StructType &); // Do not implement - const StructType &operator=(const StructType &); // Do not implement + StructType(const StructType &) LLVM_DELETED_FUNCTION; + const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION; StructType(LLVMContext &C) : CompositeType(C, StructTyID), SymbolTableEntry(0) {} enum { @@ -292,7 +290,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const StructType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == StructTyID; } @@ -308,8 +305,8 @@ public: /// class SequentialType : public CompositeType { Type *ContainedType; ///< Storage for the single contained type. - SequentialType(const SequentialType &); // Do not implement! - const SequentialType &operator=(const SequentialType &); // Do not implement! + SequentialType(const SequentialType &) LLVM_DELETED_FUNCTION; + const SequentialType &operator=(const SequentialType &) LLVM_DELETED_FUNCTION; protected: SequentialType(TypeID TID, Type *ElType) @@ -322,7 +319,6 @@ public: Type *getElementType() const { return ContainedTys[0]; } // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const SequentialType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == PointerTyID || @@ -336,8 +332,8 @@ public: class ArrayType : public SequentialType { uint64_t NumElements; - ArrayType(const ArrayType &); // Do not implement - const ArrayType &operator=(const ArrayType &); // Do not implement + ArrayType(const ArrayType &) LLVM_DELETED_FUNCTION; + const ArrayType &operator=(const ArrayType &) LLVM_DELETED_FUNCTION; ArrayType(Type *ElType, uint64_t NumEl); public: /// ArrayType::get - This static method is the primary way to construct an @@ -352,7 +348,6 @@ public: uint64_t getNumElements() const { return NumElements; } // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const ArrayType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID; } @@ -363,8 +358,8 @@ public: class VectorType : public SequentialType { unsigned NumElements; - VectorType(const VectorType &); // Do not implement - const VectorType &operator=(const VectorType &); // Do not implement + VectorType(const VectorType &) LLVM_DELETED_FUNCTION; + const VectorType &operator=(const VectorType &) LLVM_DELETED_FUNCTION; VectorType(Type *ElType, unsigned NumEl); public: /// VectorType::get - This static method is the primary way to construct an @@ -419,7 +414,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const VectorType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == VectorTyID; } @@ -429,8 +423,8 @@ public: /// PointerType - Class to represent pointers. /// class PointerType : public SequentialType { - PointerType(const PointerType &); // Do not implement - const PointerType &operator=(const PointerType &); // Do not implement + PointerType(const PointerType &) LLVM_DELETED_FUNCTION; + const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION; explicit PointerType(Type *ElType, unsigned AddrSpace); public: /// PointerType::get - This constructs a pointer to an object of the specified @@ -451,7 +445,6 @@ public: inline unsigned getAddressSpace() const { return getSubclassData(); } // Implement support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const PointerType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == PointerTyID; } diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index ae8b68d..8073d8f 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -42,7 +42,7 @@ class JITMemoryManager; class MachineCodeInfo; class Module; class MutexGuard; -class TargetData; +class DataLayout; class Triple; class Type; @@ -88,7 +88,7 @@ public: /// \brief Erase an entry from the mapping table. /// - /// \returns The address that \arg ToUnmap was happed to. + /// \returns The address that \p ToUnmap was happed to. void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap); }; @@ -104,7 +104,7 @@ class ExecutionEngine { ExecutionEngineState EEState; /// The target data for the platform for which execution is being performed. - const TargetData *TD; + const DataLayout *TD; /// Whether lazy JIT compilation is enabled. bool CompilingLazily; @@ -123,7 +123,7 @@ protected: /// optimize for the case where there is only one module. SmallVector<Module*, 1> Modules; - void setTargetData(const TargetData *td) { TD = td; } + void setDataLayout(const DataLayout *td) { TD = td; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -213,7 +213,7 @@ public: //===--------------------------------------------------------------------===// - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return TD; } /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. @@ -244,11 +244,18 @@ public: /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. - virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) { + virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) { llvm_unreachable("Re-mapping of section addresses not supported with this " "EE!"); } + // finalizeObject - This method should be called after sections within an + // object have been relocated using mapSectionAddress. When this method is + // called the MCJIT execution engine will reapply relocations for a loaded + // object. This method has no effect for the legacy JIT engine or the + // interpeter. + virtual void finalizeObject() {} + /// runStaticConstructorsDestructors - This method is used to execute all of /// the static constructors or destructors for a program. /// diff --git a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h b/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h deleted file mode 100644 index ca87342..0000000 --- a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h +++ /dev/null @@ -1,102 +0,0 @@ -//===-- IntelJITEventsWrapper.h - Intel JIT Events API Wrapper --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a wrapper for the Intel JIT Events API. It allows for the -// implementation of the jitprofiling library to be swapped with an alternative -// implementation (for testing). To include this file, you must have the -// jitprofiling.h header available; it is available in Intel(R) VTune(TM) -// Amplifier XE 2011. -// -//===----------------------------------------------------------------------===// - -#ifndef INTEL_JIT_EVENTS_WRAPPER_H -#define INTEL_JIT_EVENTS_WRAPPER_H - -#include <jitprofiling.h> - -namespace llvm { - -class IntelJITEventsWrapper { - // Function pointer types for testing implementation of Intel jitprofiling - // library - typedef int (*NotifyEventPtr)(iJIT_JVM_EVENT, void*); - typedef void (*RegisterCallbackExPtr)(void *, iJIT_ModeChangedEx ); - typedef iJIT_IsProfilingActiveFlags (*IsProfilingActivePtr)(void); - typedef void (*FinalizeThreadPtr)(void); - typedef void (*FinalizeProcessPtr)(void); - typedef unsigned int (*GetNewMethodIDPtr)(void); - - NotifyEventPtr NotifyEventFunc; - RegisterCallbackExPtr RegisterCallbackExFunc; - IsProfilingActivePtr IsProfilingActiveFunc; - FinalizeThreadPtr FinalizeThreadFunc; - FinalizeProcessPtr FinalizeProcessFunc; - GetNewMethodIDPtr GetNewMethodIDFunc; - -public: - bool isAmplifierRunning() { - return iJIT_IsProfilingActive() == iJIT_SAMPLING_ON; - } - - IntelJITEventsWrapper() - : NotifyEventFunc(::iJIT_NotifyEvent), - RegisterCallbackExFunc(::iJIT_RegisterCallbackEx), - IsProfilingActiveFunc(::iJIT_IsProfilingActive), - FinalizeThreadFunc(::FinalizeThread), - FinalizeProcessFunc(::FinalizeProcess), - GetNewMethodIDFunc(::iJIT_GetNewMethodID) { - } - - IntelJITEventsWrapper(NotifyEventPtr NotifyEventImpl, - RegisterCallbackExPtr RegisterCallbackExImpl, - IsProfilingActivePtr IsProfilingActiveImpl, - FinalizeThreadPtr FinalizeThreadImpl, - FinalizeProcessPtr FinalizeProcessImpl, - GetNewMethodIDPtr GetNewMethodIDImpl) - : NotifyEventFunc(NotifyEventImpl), - RegisterCallbackExFunc(RegisterCallbackExImpl), - IsProfilingActiveFunc(IsProfilingActiveImpl), - FinalizeThreadFunc(FinalizeThreadImpl), - FinalizeProcessFunc(FinalizeProcessImpl), - GetNewMethodIDFunc(GetNewMethodIDImpl) { - } - - // Sends an event anncouncing that a function has been emitted - // return values are event-specific. See Intel documentation for details. - int iJIT_NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) { - if (!NotifyEventFunc) - return -1; - return NotifyEventFunc(EventType, EventSpecificData); - } - - // Registers a callback function to receive notice of profiling state changes - void iJIT_RegisterCallbackEx(void *UserData, - iJIT_ModeChangedEx NewModeCallBackFuncEx) { - if (RegisterCallbackExFunc) - RegisterCallbackExFunc(UserData, NewModeCallBackFuncEx); - } - - // Returns the current profiler mode - iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive(void) { - if (!IsProfilingActiveFunc) - return iJIT_NOTHING_RUNNING; - return IsProfilingActiveFunc(); - } - - // Generates a locally unique method ID for use in code registration - unsigned int iJIT_GetNewMethodID(void) { - if (!GetNewMethodIDFunc) - return -1; - return GetNewMethodIDFunc(); - } -}; - -} //namespace llvm - -#endif //INTEL_JIT_EVENTS_WRAPPER_H diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index eea603f..e6586e7 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -26,6 +26,7 @@ class Function; class MachineFunction; class OProfileWrapper; class IntelJITEventsWrapper; +class ObjectImage; /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -76,6 +77,20 @@ public: /// matching NotifyFreeingMachineCode call. virtual void NotifyFreeingMachineCode(void *) {} + /// NotifyObjectEmitted - Called after an object has been successfully + /// emitted to memory. NotifyFunctionEmitted will not be called for + /// individual functions in the object. + /// + /// ELF-specific information + /// The ObjectImage contains the generated object image + /// with section headers updated to reflect the address at which sections + /// were loaded and with relocations performed in-place on debug sections. + virtual void NotifyObjectEmitted(const ObjectImage &Obj) {} + + /// NotifyFreeingObject - Called just before the memory associated with + /// a previously emitted object is released. + virtual void NotifyFreeingObject(const ObjectImage &Obj) {} + #if LLVM_USE_INTEL_JITEVENTS // Construct an IntelJITEventListener static JITEventListener *createIntelJITEventListener(); diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 4c75b6a..9089646 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -10,7 +10,9 @@ #ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H #define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Support/DataTypes.h" + #include <string> namespace llvm { @@ -22,7 +24,7 @@ namespace llvm { /// memory for the code generated by the JIT. This can be reimplemented by /// clients that have a strong desire to control how the layout of JIT'd memory /// works. -class JITMemoryManager { +class JITMemoryManager : public RTDyldMemoryManager { protected: bool HasGOT; @@ -47,17 +49,6 @@ public: /// debugging, and may be turned on by default in debug mode. virtual void setPoisonMemory(bool poison) = 0; - /// getPointerToNamedFunction - This method returns the address of the - /// specified function. As such it is only useful for resolving library - /// symbols, not code generated symbols. - /// - /// If AbortOnFailure is false and no function with the given name is - /// found, this function silently returns a null pointer. Otherwise, - /// it prints a message to stderr and aborts. - /// - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true) = 0; - //===--------------------------------------------------------------------===// // Global Offset Table Management //===--------------------------------------------------------------------===// @@ -112,22 +103,6 @@ public: virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, uint8_t *FunctionEnd) = 0; - /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. The SectionID is a unique identifier - /// assigned by the JIT and passed through to the memory manager for - /// the instance class to use if it needs to communicate to the JIT about - /// a given section after the fact. - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 0; - - /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. The SectionID is a unique identifier - /// assigned by the JIT and passed through to the memory manager for - /// the instance class to use if it needs to communicate to the JIT about - /// a given section after the fact. - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 0; - /// allocateSpace - Allocate a memory block of the given size. This method /// cannot be called between calls to startFunctionBody and endFunctionBody. virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0; diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h new file mode 100644 index 0000000..a0a77b8 --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -0,0 +1,80 @@ +//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a wrapper class to hold the memory into which an
+// object will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+
+/// ObjectBuffer - This class acts as a container for the memory buffer used during
+/// generation and loading of executable objects using MCJIT and RuntimeDyld. The
+/// underlying memory for the object will be owned by the ObjectBuffer instance
+/// throughout its lifetime. The getMemBuffer() method provides a way to create a
+/// MemoryBuffer wrapper object instance to be owned by other classes (such as
+/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
+/// actual memory it points to.
+class ObjectBuffer {
+public:
+ ObjectBuffer() {}
+ ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
+ virtual ~ObjectBuffer() {}
+
+ /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
+ /// returns a pointer to an object that is owned by the caller. However,
+ /// the caller does not take ownership of the underlying memory.
+ MemoryBuffer *getMemBuffer() const {
+ return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
+ }
+
+ const char *getBufferStart() const { return Buffer->getBufferStart(); }
+ size_t getBufferSize() const { return Buffer->getBufferSize(); }
+
+protected:
+ // The memory contained in an ObjectBuffer
+ OwningPtr<MemoryBuffer> Buffer;
+};
+
+/// ObjectBufferStream - This class encapsulates the SmallVector and
+/// raw_svector_ostream needed to generate an object using MC code emission
+/// while providing a common ObjectBuffer interface for access to the
+/// memory once the object has been generated.
+class ObjectBufferStream : public ObjectBuffer {
+public:
+ ObjectBufferStream() : OS(SV) {}
+ virtual ~ObjectBufferStream() {}
+
+ raw_ostream &getOStream() { return OS; }
+ void flush()
+ {
+ OS.flush();
+
+ // Make the data accessible via the ObjectBuffer::Buffer
+ Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
+ "",
+ false));
+ }
+
+protected:
+ SmallVector<char, 4096> SV; // Working buffer into which we JIT.
+ raw_svector_ostream OS; // streaming wrapper
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h new file mode 100644 index 0000000..82549ad --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectImage.h @@ -0,0 +1,61 @@ +//===---- ObjectImage.h - Format independent executuable object image -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+
+/// ObjectImage - A container class that represents an ObjectFile that has been
+/// or is in the process of being loaded into memory for execution.
+class ObjectImage {
+ ObjectImage() LLVM_DELETED_FUNCTION;
+ ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
+
+protected:
+ OwningPtr<ObjectBuffer> Buffer;
+
+public:
+ ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
+ virtual ~ObjectImage() {}
+
+ virtual object::symbol_iterator begin_symbols() const = 0;
+ virtual object::symbol_iterator end_symbols() const = 0;
+
+ virtual object::section_iterator begin_sections() const = 0;
+ virtual object::section_iterator end_sections() const = 0;
+
+ virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) = 0;
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym,
+ uint64_t Addr) = 0;
+
+ virtual StringRef getData() const = 0;
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() = 0;
+ virtual void deregisterWithDebugger() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index a5c9272..891f534 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,43 +15,55 @@ #define LLVM_RUNTIME_DYLD_H #include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/Support/Memory.h" namespace llvm { class RuntimeDyldImpl; -class MemoryBuffer; +class ObjectImage; // RuntimeDyld clients often want to handle the memory management of -// what gets placed where. For JIT clients, this is an abstraction layer -// over the JITMemoryManager, which references objects by their source -// representations in LLVM IR. +// what gets placed where. For JIT clients, this is the subset of +// JITMemoryManager required for dynamic loading of binaries. +// // FIXME: As the RuntimeDyld fills out, additional routines will be needed // for the varying types of objects to be allocated. class RTDyldMemoryManager { - RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT - void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT + RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; + void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; public: RTDyldMemoryManager() {} virtual ~RTDyldMemoryManager(); /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. + /// size suitable for executable code. The SectionID is a unique identifier + /// assigned by the JIT engine, and optionally recorded by the memory manager + /// to access a loaded section. virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. + /// size suitable for data. The SectionID is a unique identifier + /// assigned by the JIT engine, and optionally recorded by the memory manager + /// to access a loaded section. virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; + /// getPointerToNamedFunction - This method returns the address of the + /// specified function. As such it is only useful for resolving library + /// symbols, not code generated symbols. + /// + /// If AbortOnFailure is false and no function with the given name is + /// found, this function returns a null pointer. Otherwise, it prints a + /// message to stderr and aborts. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; }; class RuntimeDyld { - RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT - void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT + RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION; + void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION; // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // interface. @@ -62,17 +74,24 @@ protected: // Any relocations already associated with the symbol will be re-resolved. void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: - RuntimeDyld(RTDyldMemoryManager*); + RuntimeDyld(RTDyldMemoryManager *); ~RuntimeDyld(); - /// Load an in-memory object file into the dynamic linker. - bool loadObject(MemoryBuffer *InputBuffer); + /// loadObject - prepare the object contained in the input buffer for + /// execution. Ownership of the input buffer is transferred to the + /// ObjectImage instance returned from this function if successful. + /// In the case of load failure, the input buffer will be deleted. + ObjectImage *loadObject(ObjectBuffer *InputBuffer); /// Get the address of our local copy of the symbol. This may or may not /// be the address used for relocation (clients can copy the data around /// and resolve relocatons based on where they put it). void *getSymbolAddress(StringRef Name); + /// Get the address of the target copy of the symbol. This is the address + /// used for relocation. + uint64_t getSymbolLoadAddress(StringRef Name); + /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); @@ -80,7 +99,7 @@ public: /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. - void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress); + void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); StringRef getErrorString(); }; diff --git a/include/llvm/Function.h b/include/llvm/Function.h index fdd90d1..e211e9a 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -109,9 +109,9 @@ private: BuildLazyArguments(); } void BuildLazyArguments() const; - - Function(const Function&); // DO NOT IMPLEMENT - void operator=(const Function&); // DO NOT IMPLEMENT + + Function(const Function&) LLVM_DELETED_FUNCTION; + void operator=(const Function&) LLVM_DELETED_FUNCTION; /// Function ctor - If the (optional) Module argument is specified, the /// function is automatically inserted into the end of the function list for @@ -168,17 +168,17 @@ public: /// void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; } - /// hasFnAttr - Return true if this function has the given attribute. - bool hasFnAttr(Attributes N) const { - // Function Attributes are stored at ~0 index - return AttributeList.paramHasAttr(~0U, N); + /// getFnAttributes - Return the function attributes for querying. + /// + Attributes getFnAttributes() const { + return AttributeList.getFnAttributes(); } /// addFnAttr - Add function attributes to this function. /// - void addFnAttr(Attributes N) { + void addFnAttr(Attributes::AttrVal N) { // Function Attributes are stored at ~0 index - addAttribute(~0U, N); + addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), N)); } /// removeFnAttr - Remove function attributes from this function. @@ -195,9 +195,15 @@ public: void setGC(const char *Str); void clearGC(); - /// @brief Determine whether the function has the given attribute. - bool paramHasAttr(unsigned i, Attributes attr) const { - return AttributeList.paramHasAttr(i, attr); + + /// getRetAttributes - Return the return attributes for querying. + Attributes getRetAttributes() const { + return AttributeList.getRetAttributes(); + } + + /// getParamAttributes - Return the parameter attributes for querying. + Attributes getParamAttributes(unsigned Idx) const { + return AttributeList.getParamAttributes(Idx); } /// addAttribute - adds the attribute to the list of attributes. @@ -213,50 +219,44 @@ public: /// @brief Determine if the function does not access memory. bool doesNotAccessMemory() const { - return hasFnAttr(Attribute::ReadNone); + return getFnAttributes().hasAttribute(Attributes::ReadNone); } - void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) { - if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone); - else removeFnAttr(Attribute::ReadNone); + void setDoesNotAccessMemory() { + addFnAttr(Attributes::ReadNone); } /// @brief Determine if the function does not access or only reads memory. bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); + return doesNotAccessMemory() || + getFnAttributes().hasAttribute(Attributes::ReadOnly); } - void setOnlyReadsMemory(bool OnlyReadsMemory = true) { - if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly); - else removeFnAttr(Attribute::ReadOnly | Attribute::ReadNone); + void setOnlyReadsMemory() { + addFnAttr(Attributes::ReadOnly); } /// @brief Determine if the function cannot return. bool doesNotReturn() const { - return hasFnAttr(Attribute::NoReturn); + return getFnAttributes().hasAttribute(Attributes::NoReturn); } - void setDoesNotReturn(bool DoesNotReturn = true) { - if (DoesNotReturn) addFnAttr(Attribute::NoReturn); - else removeFnAttr(Attribute::NoReturn); + void setDoesNotReturn() { + addFnAttr(Attributes::NoReturn); } /// @brief Determine if the function cannot unwind. bool doesNotThrow() const { - return hasFnAttr(Attribute::NoUnwind); + return getFnAttributes().hasAttribute(Attributes::NoUnwind); } - void setDoesNotThrow(bool DoesNotThrow = true) { - if (DoesNotThrow) addFnAttr(Attribute::NoUnwind); - else removeFnAttr(Attribute::NoUnwind); + void setDoesNotThrow() { + addFnAttr(Attributes::NoUnwind); } /// @brief True if the ABI mandates (or the user requested) that this /// function be in a unwind table. bool hasUWTable() const { - return hasFnAttr(Attribute::UWTable); + return getFnAttributes().hasAttribute(Attributes::UWTable); } - void setHasUWTable(bool HasUWTable = true) { - if (HasUWTable) - addFnAttr(Attribute::UWTable); - else - removeFnAttr(Attribute::UWTable); + void setHasUWTable() { + addFnAttr(Attributes::UWTable); } /// @brief True if this function needs an unwind table. @@ -267,27 +267,25 @@ public: /// @brief Determine if the function returns a structure through first /// pointer argument. bool hasStructRetAttr() const { - return paramHasAttr(1, Attribute::StructRet); + return getParamAttributes(1).hasAttribute(Attributes::StructRet); } /// @brief Determine if the parameter does not alias other parameters. /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool doesNotAlias(unsigned n) const { - return paramHasAttr(n, Attribute::NoAlias); + return getParamAttributes(n).hasAttribute(Attributes::NoAlias); } - void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) { - if (DoesNotAlias) addAttribute(n, Attribute::NoAlias); - else removeAttribute(n, Attribute::NoAlias); + void setDoesNotAlias(unsigned n) { + addAttribute(n, Attributes::get(getContext(), Attributes::NoAlias)); } /// @brief Determine if the parameter can be captured. /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool doesNotCapture(unsigned n) const { - return paramHasAttr(n, Attribute::NoCapture); + return getParamAttributes(n).hasAttribute(Attributes::NoCapture); } - void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) { - if (DoesNotCapture) addAttribute(n, Attribute::NoCapture); - else removeAttribute(n, Attribute::NoCapture); + void setDoesNotCapture(unsigned n) { + addAttribute(n, Attributes::get(getContext(), Attributes::NoCapture)); } /// copyAttributesFrom - copy all additional attributes (those not needed to @@ -400,7 +398,6 @@ public: void viewCFGOnly() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Function *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal; } diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index 164d976..d0f0147 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -28,8 +28,8 @@ template<typename ValueSubClass, typename ItemParentClass> class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> { friend class SymbolTableListTraits<GlobalAlias, Module>; - void operator=(const GlobalAlias &); // Do not implement - GlobalAlias(const GlobalAlias &); // Do not implement + void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION; + GlobalAlias(const GlobalAlias &) LLVM_DELETED_FUNCTION; void setParent(Module *parent); @@ -76,7 +76,6 @@ public: const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalAlias *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalAliasVal; } diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 8b969f3..7f7f74b 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -26,7 +26,7 @@ class PointerType; class Module; class GlobalValue : public Constant { - GlobalValue(const GlobalValue &); // do not implement + GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION; public: /// @brief An enumeration for the kinds of linkage for global values. enum LinkageTypes { @@ -34,6 +34,7 @@ public: AvailableExternallyLinkage, ///< Available for inspection, not emission. LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline) LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent. + LinkOnceODRAutoHideLinkage, ///< Like LinkOnceODRLinkage but addr not taken. WeakAnyLinkage, ///< Keep one copy of named function when linking (weak) WeakODRLinkage, ///< Same, but only replaced by something equivalent. AppendingLinkage, ///< Special purpose, only applies to global arrays @@ -41,8 +42,6 @@ public: PrivateLinkage, ///< Like Internal, but omit from symbol table. LinkerPrivateLinkage, ///< Like Private, but linker removes. LinkerPrivateWeakLinkage, ///< Like LinkerPrivate, but weak. - LinkerPrivateWeakDefAutoLinkage, ///< Like LinkerPrivateWeak, but possibly - /// hidden. DLLImportLinkage, ///< Function to be imported from DLL DLLExportLinkage, ///< Function to be accessible from DLL. ExternalWeakLinkage,///< ExternalWeak linkage description. @@ -123,7 +122,12 @@ public: return Linkage == AvailableExternallyLinkage; } static bool isLinkOnceLinkage(LinkageTypes Linkage) { - return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; + return Linkage == LinkOnceAnyLinkage || + Linkage == LinkOnceODRLinkage || + Linkage == LinkOnceODRAutoHideLinkage; + } + static bool isLinkOnceODRAutoHideLinkage(LinkageTypes Linkage) { + return Linkage == LinkOnceODRAutoHideLinkage; } static bool isWeakLinkage(LinkageTypes Linkage) { return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage; @@ -143,13 +147,9 @@ public: static bool isLinkerPrivateWeakLinkage(LinkageTypes Linkage) { return Linkage == LinkerPrivateWeakLinkage; } - static bool isLinkerPrivateWeakDefAutoLinkage(LinkageTypes Linkage) { - return Linkage == LinkerPrivateWeakDefAutoLinkage; - } static bool isLocalLinkage(LinkageTypes Linkage) { return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) || - isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage) || - isLinkerPrivateWeakDefAutoLinkage(Linkage); + isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage); } static bool isDLLImportLinkage(LinkageTypes Linkage) { return Linkage == DLLImportLinkage; @@ -178,8 +178,7 @@ public: Linkage == LinkOnceAnyLinkage || Linkage == CommonLinkage || Linkage == ExternalWeakLinkage || - Linkage == LinkerPrivateWeakLinkage || - Linkage == LinkerPrivateWeakDefAutoLinkage; + Linkage == LinkerPrivateWeakLinkage; } /// isWeakForLinker - Whether the definition of this global may be replaced at @@ -192,10 +191,10 @@ public: Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage || + Linkage == LinkOnceODRAutoHideLinkage || Linkage == CommonLinkage || Linkage == ExternalWeakLinkage || - Linkage == LinkerPrivateWeakLinkage || - Linkage == LinkerPrivateWeakDefAutoLinkage; + Linkage == LinkerPrivateWeakLinkage; } bool hasExternalLinkage() const { return isExternalLinkage(Linkage); } @@ -205,6 +204,9 @@ public: bool hasLinkOnceLinkage() const { return isLinkOnceLinkage(Linkage); } + bool hasLinkOnceODRAutoHideLinkage() const { + return isLinkOnceODRAutoHideLinkage(Linkage); + } bool hasWeakLinkage() const { return isWeakLinkage(Linkage); } @@ -215,9 +217,6 @@ public: bool hasLinkerPrivateWeakLinkage() const { return isLinkerPrivateWeakLinkage(Linkage); } - bool hasLinkerPrivateWeakDefAutoLinkage() const { - return isLinkerPrivateWeakDefAutoLinkage(Linkage); - } bool hasLocalLinkage() const { return isLocalLinkage(Linkage); } bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); } bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); } @@ -288,7 +287,6 @@ public: inline const Module *getParent() const { return Parent; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal || diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 99b7a73..b9d3f68 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -34,9 +34,9 @@ template<typename ValueSubClass, typename ItemParentClass> class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> { friend class SymbolTableListTraits<GlobalVariable, Module>; - void *operator new(size_t, unsigned); // Do not implement - void operator=(const GlobalVariable &); // Do not implement - GlobalVariable(const GlobalVariable &); // Do not implement + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION; + GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION; void setParent(Module *parent); @@ -174,7 +174,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalVariable *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; } diff --git a/include/llvm/IRBuilder.h b/include/llvm/IRBuilder.h index d5b6f47..f63a160 100644 --- a/include/llvm/IRBuilder.h +++ b/include/llvm/IRBuilder.h @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/BasicBlock.h" +#include "llvm/DataLayout.h" #include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -266,6 +267,10 @@ public: return Type::getInt8PtrTy(Context, AddrSpace); } + IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) { + return DL->getIntPtrType(Context, AddrSpace); + } + //===--------------------------------------------------------------------===// // Intrinsic creation methods //===--------------------------------------------------------------------===// @@ -285,12 +290,15 @@ public: /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align, - bool isVolatile = false, MDNode *TBAATag = 0) { - return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); + bool isVolatile = false, MDNode *TBAATag = 0, + MDNode *TBAAStructTag = 0) { + return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag, + TBAAStructTag); } CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, - bool isVolatile = false, MDNode *TBAATag = 0); + bool isVolatile = false, MDNode *TBAATag = 0, + MDNode *TBAAStructTag = 0); /// CreateMemMove - Create and insert a memmove between the specified /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA @@ -810,6 +818,31 @@ public: StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } + // Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' correctly, + // instead of converting the string to 'bool' for the isVolatile parameter. + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { + LoadInst *LI = CreateLoad(Ptr, Name); + LI->setAlignment(Align); + return LI; + } + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, + const Twine &Name = "") { + LoadInst *LI = CreateLoad(Ptr, Name); + LI->setAlignment(Align); + return LI; + } + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile, + const Twine &Name = "") { + LoadInst *LI = CreateLoad(Ptr, isVolatile, Name); + LI->setAlignment(Align); + return LI; + } + StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align, + bool isVolatile = false) { + StoreInst *SI = CreateStore(Val, Ptr, isVolatile); + SI->setAlignment(Align); + return SI; + } FenceInst *CreateFence(AtomicOrdering Ordering, SynchronizationScope SynchScope = CrossThread) { return Insert(new FenceInst(Context, Ordering, SynchScope)); @@ -970,6 +1003,30 @@ public: Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } + /// CreateZExtOrTrunc - Create a ZExt or Trunc from the integer value V to + /// DestTy. Return the value untouched if the type of V is already DestTy. + Value *CreateZExtOrTrunc(Value *V, IntegerType *DestTy, + const Twine &Name = "") { + assert(isa<IntegerType>(V->getType()) && "Can only zero extend integers!"); + IntegerType *IntTy = cast<IntegerType>(V->getType()); + if (IntTy->getBitWidth() < DestTy->getBitWidth()) + return CreateZExt(V, DestTy, Name); + if (IntTy->getBitWidth() > DestTy->getBitWidth()) + return CreateTrunc(V, DestTy, Name); + return V; + } + /// CreateSExtOrTrunc - Create a SExt or Trunc from the integer value V to + /// DestTy. Return the value untouched if the type of V is already DestTy. + Value *CreateSExtOrTrunc(Value *V, IntegerType *DestTy, + const Twine &Name = "") { + assert(isa<IntegerType>(V->getType()) && "Can only sign extend integers!"); + IntegerType *IntTy = cast<IntegerType>(V->getType()); + if (IntTy->getBitWidth() < DestTy->getBitWidth()) + return CreateSExt(V, DestTy, Name); + if (IntTy->getBitWidth() > DestTy->getBitWidth()) + return CreateTrunc(V, DestTy, Name); + return V; + } Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToUI, V, DestTy, Name); } @@ -1052,7 +1109,7 @@ public: private: // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time // error, instead of converting the string to bool for the isSigned parameter. - Value *CreateIntCast(Value *, Type *, const char *); // DO NOT IMPLEMENT + Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION; public: Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) @@ -1261,13 +1318,13 @@ public: // Utility creation methods //===--------------------------------------------------------------------===// - /// CreateIsNull - Return an i1 value testing if \arg Arg is null. + /// CreateIsNull - Return an i1 value testing if \p Arg is null. Value *CreateIsNull(Value *Arg, const Twine &Name = "") { return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), Name); } - /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null. + /// CreateIsNotNull - Return an i1 value testing if \p Arg is not null. Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), Name); diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index de97957..8c164eb 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -66,6 +66,7 @@ void initializeAliasDebuggerPass(PassRegistry&); void initializeAliasSetPrinterPass(PassRegistry&); void initializeAlwaysInlinerPass(PassRegistry&); void initializeArgPromotionPass(PassRegistry&); +void initializeBarrierNoopPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); @@ -87,6 +88,7 @@ void initializeCodePlacementOptPass(PassRegistry&); void initializeConstantMergePass(PassRegistry&); void initializeConstantPropagationPass(PassRegistry&); void initializeMachineCopyPropagationPass(PassRegistry&); +void initializeCostModelAnalysisPass(PassRegistry&); void initializeCorrelatedValuePropagationPass(PassRegistry&); void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); @@ -94,6 +96,7 @@ void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); +void initializeDependenceAnalysisPass(PassRegistry&); void initializeDomOnlyPrinterPass(PassRegistry&); void initializeDomOnlyViewerPass(PassRegistry&); void initializeDomPrinterPass(PassRegistry&); @@ -141,10 +144,10 @@ void initializeLiveRegMatrixPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&); +void initializeProfileMetadataLoaderPassPass(PassRegistry&); void initializePathProfileLoaderPassPass(PassRegistry&); void initializeLocalStackSlotPassPass(PassRegistry&); void initializeLoopDeletionPass(PassRegistry&); -void initializeLoopDependenceAnalysisPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); void initializeLoopInfoPass(PassRegistry&); void initializeLoopInstSimplifyPass(PassRegistry&); @@ -166,6 +169,7 @@ void initializeMachineBlockPlacementStatsPass(PassRegistry&); void initializeMachineBranchProbabilityInfoPass(PassRegistry&); void initializeMachineCSEPass(PassRegistry&); void initializeMachineDominatorTreePass(PassRegistry&); +void initializeMachinePostDominatorTreePass(PassRegistry&); void initializeMachineLICMPass(PassRegistry&); void initializeMachineLoopInfoPass(PassRegistry&); void initializeMachineLoopRangesPass(PassRegistry&); @@ -177,6 +181,7 @@ void initializeMachineVerifierPassPass(PassRegistry&); void initializeMemCpyOptPass(PassRegistry&); void initializeMemDepPrinterPass(PassRegistry&); void initializeMemoryDependenceAnalysisPass(PassRegistry&); +void initializeMetaRenamerPass(PassRegistry&); void initializeMergeFunctionsPass(PassRegistry&); void initializeModuleDebugInfoPrinterPass(PassRegistry&); void initializeNoAAPass(PassRegistry&); @@ -219,6 +224,7 @@ void initializeRegionOnlyViewerPass(PassRegistry&); void initializeRegionPrinterPass(PassRegistry&); void initializeRegionViewerPass(PassRegistry&); void initializeSCCPPass(PassRegistry&); +void initializeSROAPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&); void initializeSROA_SSAUpPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); @@ -231,6 +237,7 @@ void initializeSinkingPass(PassRegistry&); void initializeSlotIndexesPass(PassRegistry&); void initializeSpillPlacementPass(PassRegistry&); void initializeStackProtectorPass(PassRegistry&); +void initializeStackColoringPass(PassRegistry&); void initializeStackSlotColoringPass(PassRegistry&); void initializeStripDeadDebugInfoPass(PassRegistry&); void initializeStripDeadPrototypesPassPass(PassRegistry&); @@ -241,7 +248,8 @@ void initializeStrongPHIEliminationPass(PassRegistry&); void initializeTailCallElimPass(PassRegistry&); void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); -void initializeTargetDataPass(PassRegistry&); +void initializeDataLayoutPass(PassRegistry&); +void initializeTargetTransformInfoPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); void initializeTypeBasedAliasAnalysisPass(PassRegistry&); @@ -254,6 +262,7 @@ void initializeVirtRegRewriterPass(PassRegistry&); void initializeInstSimplifierPass(PassRegistry&); void initializeUnpackMachineBundlesPass(PassRegistry&); void initializeFinalizeMachineBundlesPass(PassRegistry&); +void initializeLoopVectorizePass(PassRegistry&); void initializeBBVectorizePass(PassRegistry&); void initializeMachineFunctionPrinterPassPass(PassRegistry&); } diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index 37aa18b..b5e0fd4 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -33,20 +33,28 @@ template<class ConstantClass, class TypeClass, class ValType> struct ConstantCreator; class InlineAsm : public Value { +public: + enum AsmDialect { + AD_ATT, + AD_Intel + }; + +private: friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>; friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&, PointerType, InlineAsm, false>; - InlineAsm(const InlineAsm &); // do not implement - void operator=(const InlineAsm&); // do not implement + InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION; + void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION; std::string AsmString, Constraints; bool HasSideEffects; bool IsAlignStack; - + AsmDialect Dialect; + InlineAsm(PointerType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects, - bool isAlignStack); + bool isAlignStack, AsmDialect asmDialect); virtual ~InlineAsm(); /// When the ConstantUniqueMap merges two types and makes two InlineAsms @@ -58,11 +66,13 @@ public: /// static InlineAsm *get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, - bool isAlignStack = false); + bool isAlignStack = false, + AsmDialect asmDialect = AD_ATT); bool hasSideEffects() const { return HasSideEffects; } bool isAlignStack() const { return IsAlignStack; } - + AsmDialect getDialect() const { return Dialect; } + /// getType - InlineAsm's are always pointers. /// PointerType *getType() const { @@ -179,7 +189,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InlineAsm *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::InlineAsmVal; } @@ -193,17 +202,20 @@ public: Op_InputChain = 0, Op_AsmString = 1, Op_MDNode = 2, - Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack + Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect. Op_FirstOperand = 4, // Fixed operands on an INLINEASM MachineInstr. MIOp_AsmString = 0, - MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack + MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect. MIOp_FirstOperand = 2, // Interpretation of the MIOp_ExtraInfo bit field. Extra_HasSideEffects = 1, Extra_IsAlignStack = 2, + Extra_AsmDialect = 4, + Extra_MayLoad = 8, + Extra_MayStore = 16, // Inline asm operands map to multiple SDNode / MachineInstr operands. // The first operand is an immediate describing the asm operand, the low diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 2529f24..da17f3b 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -73,7 +73,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const TerminatorInst *) { return true; } static inline bool classof(const Instruction *I) { return I->isTerminator(); } @@ -88,7 +87,7 @@ public: //===----------------------------------------------------------------------===// class UnaryInstruction : public Instruction { - void *operator new(size_t, unsigned); // Do not implement + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; protected: UnaryInstruction(Type *Ty, unsigned iType, Value *V, @@ -113,7 +112,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UnaryInstruction *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || @@ -138,14 +136,14 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) //===----------------------------------------------------------------------===// class BinaryOperator : public Instruction { - void *operator new(size_t, unsigned); // Do not implement + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; protected: void init(BinaryOps iType); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); - virtual BinaryOperator *clone_impl() const; + virtual BinaryOperator *clone_impl() const LLVM_OVERRIDE; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -361,7 +359,6 @@ public: bool isExact() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->isBinaryOp(); } @@ -388,7 +385,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) /// if (isa<CastInst>(Instr)) { ... } /// @brief Base class of casting instructions. class CastInst : public UnaryInstruction { - virtual void anchor(); + virtual void anchor() LLVM_OVERRIDE; protected: /// @brief Constructor with insert-before-instruction semantics for subclasses CastInst(Type *Ty, unsigned iType, Value *S, @@ -563,7 +560,7 @@ public: /// IntPtrTy argument is used to make accurate determinations for casts /// involving Integer and Pointer types. They are no-op casts if the integer /// is the same size as the pointer. However, pointer size varies with - /// platform. Generally, the result of TargetData::getIntPtrType() should be + /// platform. Generally, the result of DataLayout::getIntPtrType() should be /// passed in. If that's not available, use Type::Int64Ty, which will make /// the isNoopCast call conservative. /// @brief Determine if the described cast is a no-op cast. @@ -581,8 +578,8 @@ public: /// Determine how a pair of casts can be eliminated, if they can be at all. /// This is a helper function for both CastInst and ConstantExpr. - /// @returns 0 if the CastInst pair can't be eliminated - /// @returns Instruction::CastOps value for a cast that can replace + /// @returns 0 if the CastInst pair can't be eliminated, otherwise + /// returns Instruction::CastOps value for a cast that can replace /// the pair, casting SrcTy to DstTy. /// @brief Determine if a cast pair is eliminable static unsigned isEliminableCastPair( @@ -591,7 +588,9 @@ public: Type *SrcTy, ///< SrcTy of 1st cast Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast Type *DstTy, ///< DstTy of 2nd cast - Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null + Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null + Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null + Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null ); /// @brief Return the opcode of this CastInst @@ -611,7 +610,6 @@ public: static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CastInst *) { return true; } static inline bool classof(const Instruction *I) { return I->isCast(); } @@ -627,8 +625,8 @@ public: /// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. class CmpInst : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - CmpInst(); // do not implement + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + CmpInst() LLVM_DELETED_FUNCTION; protected: CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS, const Twine &Name = "", @@ -638,7 +636,7 @@ protected: Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd); - virtual void Anchor() const; // Out of line virtual method. + virtual void anchor() LLVM_OVERRIDE; // Out of line virtual method. public: /// This enumeration lists the possible predicates for CmpInst subclasses. /// Values in the range 0-31 are reserved for FCmpInst, while values in the @@ -816,7 +814,6 @@ public: static bool isFalseWhenEqual(unsigned short predicate); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CmpInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp || I->getOpcode() == Instruction::FCmp; diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 5512dcc..8aa8a56 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -28,8 +28,8 @@ template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; class Instruction : public User, public ilist_node<Instruction> { - void operator=(const Instruction &); // Do not implement - Instruction(const Instruction &); // Do not implement + void operator=(const Instruction &) LLVM_DELETED_FUNCTION; + Instruction(const Instruction &) LLVM_DELETED_FUNCTION; BasicBlock *Parent; DebugLoc DbgLoc; // 'dbg' Metadata cache. @@ -310,7 +310,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() >= Value::InstructionVal; } diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index f5187e6..69593b4 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -112,7 +112,6 @@ public: bool isStaticAlloca() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AllocaInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Alloca); } @@ -226,13 +225,13 @@ public: const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } + /// \brief Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace(); + return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const LoadInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; } @@ -255,7 +254,7 @@ private: /// StoreInst - an instruction for storing to memory /// class StoreInst : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void AssertOK(); protected: virtual StoreInst *clone_impl() const; @@ -349,12 +348,12 @@ public: const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } + /// \brief Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace(); + return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const StoreInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; } @@ -382,7 +381,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) /// FenceInst - an instruction for ordering other memory operations /// class FenceInst : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); protected: virtual FenceInst *clone_impl() const; @@ -426,7 +425,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FenceInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Fence; } @@ -450,7 +448,7 @@ private: /// there. Returns the value that was loaded. /// class AtomicCmpXchgInst : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void Init(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering Ordering, SynchronizationScope SynchScope); protected: @@ -521,12 +519,12 @@ public: Value *getNewValOperand() { return getOperand(2); } const Value *getNewValOperand() const { return getOperand(2); } + /// \brief Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace(); + return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AtomicCmpXchgInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; } @@ -557,7 +555,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) /// the old value. /// class AtomicRMWInst : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; protected: virtual AtomicRMWInst *clone_impl() const; public: @@ -665,12 +663,12 @@ public: Value *getValOperand() { return getOperand(1); } const Value *getValOperand() const { return getOperand(1); } + /// \brief Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace(); + return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AtomicRMWInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; } @@ -768,6 +766,13 @@ public: return reinterpret_cast<PointerType*>(Instruction::getType()); } + /// \brief Returns the address space of this instruction's pointer type. + unsigned getAddressSpace() const { + // Note that this is always the same as the pointer operand's address space + // and that is cheaper to compute, so cheat here. + return getPointerAddressSpace(); + } + /// getIndexedType - Returns the type of the element that would be loaded with /// a load instruction with the specified parameters. /// @@ -778,10 +783,6 @@ public: static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList); static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList); - /// getIndexedType - Returns the address space used by the GEP pointer. - /// - static unsigned getAddressSpace(Value *Ptr); - inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } inline op_iterator idx_end() { return op_end(); } @@ -797,22 +798,23 @@ public: return 0U; // get index for modifying correct operand. } - unsigned getPointerAddressSpace() const { - return cast<PointerType>(getType())->getAddressSpace(); - } - /// getPointerOperandType - Method to return the pointer operand as a /// PointerType. Type *getPointerOperandType() const { return getPointerOperand()->getType(); } + /// \brief Returns the address space of the pointer operand. + unsigned getPointerAddressSpace() const { + return getPointerOperandType()->getPointerAddressSpace(); + } + /// GetGEPReturnType - Returns the pointer type returned by the GEP /// instruction, which may be a vector of pointers. static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) { Type *PtrTy = PointerType::get(checkGEPType( getIndexedType(Ptr->getType(), IdxList)), - getAddressSpace(Ptr)); + Ptr->getType()->getPointerAddressSpace()); // Vector GEP if (Ptr->getType()->isVectorTy()) { unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements(); @@ -849,7 +851,6 @@ public: bool isInBounds() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GetElementPtrInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); } @@ -897,13 +898,13 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// This instruction compares its operands according to the predicate given /// to the constructor. It only operates on integers or pointers. The operands /// must be identical types. -/// @brief Represent an integer comparison operator. +/// \brief Represent an integer comparison operator. class ICmpInst: public CmpInst { protected: - /// @brief Clone an identical ICmpInst + /// \brief Clone an identical ICmpInst virtual ICmpInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics. + /// \brief Constructor with insert-before-instruction semantics. ICmpInst( Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison @@ -924,7 +925,7 @@ public: "Invalid operand types for ICmp instruction"); } - /// @brief Constructor with insert-at-end semantics. + /// \brief Constructor with insert-at-end semantics. ICmpInst( BasicBlock &InsertAtEnd, ///< Block to insert into. Predicate pred, ///< The predicate to use for the comparison @@ -945,7 +946,7 @@ public: "Invalid operand types for ICmp instruction"); } - /// @brief Constructor with no-insertion semantics + /// \brief Constructor with no-insertion semantics ICmpInst( Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression @@ -967,25 +968,25 @@ public: /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc. /// @returns the predicate that would be the result if the operand were /// regarded as signed. - /// @brief Return the signed version of the predicate + /// \brief Return the signed version of the predicate Predicate getSignedPredicate() const { return getSignedPredicate(getPredicate()); } /// This is a static version that you can use without an instruction. - /// @brief Return the signed version of the predicate. + /// \brief Return the signed version of the predicate. static Predicate getSignedPredicate(Predicate pred); /// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc. /// @returns the predicate that would be the result if the operand were /// regarded as unsigned. - /// @brief Return the unsigned version of the predicate + /// \brief Return the unsigned version of the predicate Predicate getUnsignedPredicate() const { return getUnsignedPredicate(getPredicate()); } /// This is a static version that you can use without an instruction. - /// @brief Return the unsigned version of the predicate. + /// \brief Return the unsigned version of the predicate. static Predicate getUnsignedPredicate(Predicate pred); /// isEquality - Return true if this predicate is either EQ or NE. This also @@ -1001,7 +1002,7 @@ public: } /// @returns true if the predicate of this ICmpInst is commutative - /// @brief Determine if this relation is commutative. + /// \brief Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } /// isRelational - Return true if the predicate is relational (not EQ or NE). @@ -1017,21 +1018,20 @@ public: } /// Initialize a set of values that all satisfy the predicate with C. - /// @brief Make a ConstantRange for a relation with a constant value. + /// \brief Make a ConstantRange for a relation with a constant value. static ConstantRange makeConstantRange(Predicate pred, const APInt &C); /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent /// (e.g. ult). - /// @brief Swap operands and adjust predicate. + /// \brief Swap operands and adjust predicate. void swapOperands() { setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp; } @@ -1048,13 +1048,13 @@ public: /// This instruction compares its operands according to the predicate given /// to the constructor. It only operates on floating point values or packed /// vectors of floating point values. The operands must be identical types. -/// @brief Represents a floating point comparison operator. +/// \brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { protected: - /// @brief Clone an identical FCmpInst + /// \brief Clone an identical FCmpInst virtual FCmpInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics. + /// \brief Constructor with insert-before-instruction semantics. FCmpInst( Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison @@ -1073,7 +1073,7 @@ public: "Invalid operand types for FCmp instruction"); } - /// @brief Constructor with insert-at-end semantics. + /// \brief Constructor with insert-at-end semantics. FCmpInst( BasicBlock &InsertAtEnd, ///< Block to insert into. Predicate pred, ///< The predicate to use for the comparison @@ -1092,7 +1092,7 @@ public: "Invalid operand types for FCmp instruction"); } - /// @brief Constructor with no-insertion semantics + /// \brief Constructor with no-insertion semantics FCmpInst( Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression @@ -1110,14 +1110,14 @@ public: } /// @returns true if the predicate of this instruction is EQ or NE. - /// @brief Determine if this is an equality predicate. + /// \brief Determine if this is an equality predicate. bool isEquality() const { return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE || getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE; } /// @returns true if the predicate of this instruction is commutative. - /// @brief Determine if this is a commutative predicate. + /// \brief Determine if this is a commutative predicate. bool isCommutative() const { return isEquality() || getPredicate() == FCMP_FALSE || @@ -1127,21 +1127,20 @@ public: } /// @returns true if the predicate is relational (not EQ or NE). - /// @brief Determine if this a relational predicate. + /// \brief Determine if this a relational predicate. bool isRelational() const { return !isEquality(); } /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent /// (e.g. ult). - /// @brief Swap operands and adjust predicate. + /// \brief Swap operands and adjust predicate. void swapOperands() { setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FCmpInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::FCmp; } @@ -1163,12 +1162,12 @@ class CallInst : public Instruction { void init(Value *Func, const Twine &NameStr); /// Construct a CallInst given a range of arguments. - /// @brief Construct a CallInst from a range of arguments + /// \brief Construct a CallInst from a range of arguments inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, Instruction *InsertBefore); /// Construct a CallInst given a range of arguments. - /// @brief Construct a CallInst from a range of arguments + /// \brief Construct a CallInst from a range of arguments inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd); @@ -1267,77 +1266,78 @@ public: /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attributes attr); - /// \brief Return true if this call has the given attribute. - bool hasFnAttr(Attributes N) const { - return paramHasAttr(~0, N); - } + /// \brief Determine whether this call has the given attribute. + bool hasFnAttr(Attributes::AttrVal A) const; - /// @brief Determine whether the call or the callee has the given attribute. - bool paramHasAttr(unsigned i, Attributes attr) const; + /// \brief Determine whether the call or the callee has the given attributes. + bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; - /// @brief Extract the alignment for a call or parameter (0=unknown). + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); } - /// @brief Return true if the call should not be inlined. - bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } - void setIsNoInline(bool Value = true) { - if (Value) addAttribute(~0, Attribute::NoInline); - else removeAttribute(~0, Attribute::NoInline); + /// \brief Return true if the call should not be inlined. + bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } + void setIsNoInline() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoInline)); } - /// @brief Return true if the call can return twice + /// \brief Return true if the call can return twice bool canReturnTwice() const { - return hasFnAttr(Attribute::ReturnsTwice); + return hasFnAttr(Attributes::ReturnsTwice); } - void setCanReturnTwice(bool Value = true) { - if (Value) addAttribute(~0, Attribute::ReturnsTwice); - else removeAttribute(~0, Attribute::ReturnsTwice); + void setCanReturnTwice() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReturnsTwice)); } - /// @brief Determine if the call does not access memory. + /// \brief Determine if the call does not access memory. bool doesNotAccessMemory() const { - return hasFnAttr(Attribute::ReadNone); + return hasFnAttr(Attributes::ReadNone); } - void setDoesNotAccessMemory(bool NotAccessMemory = true) { - if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone); - else removeAttribute(~0, Attribute::ReadNone); + void setDoesNotAccessMemory() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadNone)); } - /// @brief Determine if the call does not access or only reads memory. + /// \brief Determine if the call does not access or only reads memory. bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); + return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } - void setOnlyReadsMemory(bool OnlyReadsMemory = true) { - if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly); - else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone); + void setOnlyReadsMemory() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadOnly)); } - /// @brief Determine if the call cannot return. - bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } - void setDoesNotReturn(bool DoesNotReturn = true) { - if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn); - else removeAttribute(~0, Attribute::NoReturn); + /// \brief Determine if the call cannot return. + bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } + void setDoesNotReturn() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoReturn)); } - /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } - void setDoesNotThrow(bool DoesNotThrow = true) { - if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind); - else removeAttribute(~0, Attribute::NoUnwind); + /// \brief Determine if the call cannot unwind. + bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } + void setDoesNotThrow() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoUnwind)); } - /// @brief Determine if the call returns a structure through first + /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { // Be friendly and also check the callee. - return paramHasAttr(1, Attribute::StructRet); + return paramHasAttr(1, Attributes::StructRet); } - /// @brief Determine if any call argument is an aggregate passed by value. + /// \brief Determine if any call argument is an aggregate passed by value. bool hasByValArgument() const { - return AttributeList.hasAttrSomewhere(Attribute::ByVal); + for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) + if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal)) + return true; + return false; } /// getCalledFunction - Return the function called, or null if this is an @@ -1363,7 +1363,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CallInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; } @@ -1469,7 +1468,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SelectInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Select; } @@ -1512,7 +1510,6 @@ public: static unsigned getPointerOperandIndex() { return 0U; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const VAArgInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == VAArg; } @@ -1566,7 +1563,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ExtractElementInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractElement; } @@ -1625,7 +1621,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InsertElementInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertElement; } @@ -1706,7 +1701,6 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ShuffleVectorInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; } @@ -1802,7 +1796,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ExtractValueInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractValue; } @@ -1839,7 +1832,7 @@ ExtractValueInst::ExtractValueInst(Value *Agg, class InsertValueInst : public Instruction { SmallVector<unsigned, 4> Indices; - void *operator new(size_t, unsigned); // Do not implement + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; InsertValueInst(const InsertValueInst &IVI); void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const Twine &NameStr); @@ -1924,7 +1917,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InsertValueInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertValue; } @@ -1970,7 +1962,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) // scientist's overactive imagination. // class PHINode : public Instruction { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; /// ReservedSpace - The number of operands actually allocated. NumOperands is /// the number actually in use. unsigned ReservedSpace; @@ -2141,7 +2133,6 @@ public: Value *hasConstantValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const PHINode *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::PHI; } @@ -2178,7 +2169,7 @@ class LandingPadInst : public Instruction { public: enum ClauseType { Catch, Filter }; private: - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; // Allocate space for exactly zero operands. void *operator new(size_t s) { return User::operator new(s, 0); @@ -2249,7 +2240,6 @@ public: void reserveClauses(unsigned Size) { growOperands(Size); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const LandingPadInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::LandingPad; } @@ -2318,7 +2308,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ReturnInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Ret); } @@ -2418,7 +2407,6 @@ public: void swapSuccessors(); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BranchInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); } @@ -2445,7 +2433,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value) /// SwitchInst - Multiway switch /// class SwitchInst : public TerminatorInst { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; unsigned ReservedSpace; // Operands format: // Operand[0] = Value to switch on @@ -2613,7 +2601,7 @@ public: } /// addCase - Add an entry to the switch instruction... - /// @Deprecated + /// @deprecated /// Note: /// This action invalidates case_end(). Old case_end() iterator will /// point to the added case. @@ -2699,7 +2687,7 @@ public: } /// Resolves case value for current case. - /// @Deprecated + /// @deprecated ConstantIntTy *getCaseValue() { assert(Index < SI->getNumCases() && "Index out the number of cases."); IntegersSubsetRef CaseRanges = *SubsetIt; @@ -2803,7 +2791,7 @@ public: CaseIt(const ParentTy& Src) : ParentTy(Src) {} /// Sets the new value for current case. - /// @Deprecated. + /// @deprecated. void setValue(ConstantInt *V) { assert(Index < SI->getNumCases() && "Index out the number of cases."); IntegersSubsetToBB Mapping; @@ -2829,7 +2817,6 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Switch; } @@ -2857,7 +2844,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value) /// IndirectBrInst - Indirect Branch Instruction. /// class IndirectBrInst : public TerminatorInst { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; unsigned ReservedSpace; // Operand[0] = Value to switch on // Operand[1] = Default basic block destination @@ -2928,7 +2915,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IndirectBrInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; } @@ -2963,14 +2949,14 @@ class InvokeInst : public TerminatorInst { /// Construct an InvokeInst given a range of arguments. /// - /// @brief Construct an InvokeInst from a range of arguments + /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore); /// Construct an InvokeInst given a range of arguments. /// - /// @brief Construct an InvokeInst from a range of arguments + /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); @@ -3029,68 +3015,69 @@ public: /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attributes attr); - /// \brief Return true if this call has the given attribute. - bool hasFnAttr(Attributes N) const { - return paramHasAttr(~0, N); - } + /// \brief Determine whether this call has the NoAlias attribute. + bool hasFnAttr(Attributes::AttrVal A) const; - /// @brief Determine whether the call or the callee has the given attribute. - bool paramHasAttr(unsigned i, Attributes attr) const; + /// \brief Determine whether the call or the callee has the given attributes. + bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; - /// @brief Extract the alignment for a call or parameter (0=unknown). + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); } - /// @brief Return true if the call should not be inlined. - bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } - void setIsNoInline(bool Value = true) { - if (Value) addAttribute(~0, Attribute::NoInline); - else removeAttribute(~0, Attribute::NoInline); + /// \brief Return true if the call should not be inlined. + bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } + void setIsNoInline() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoInline)); } - /// @brief Determine if the call does not access memory. + /// \brief Determine if the call does not access memory. bool doesNotAccessMemory() const { - return hasFnAttr(Attribute::ReadNone); + return hasFnAttr(Attributes::ReadNone); } - void setDoesNotAccessMemory(bool NotAccessMemory = true) { - if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone); - else removeAttribute(~0, Attribute::ReadNone); + void setDoesNotAccessMemory() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadNone)); } - /// @brief Determine if the call does not access or only reads memory. + /// \brief Determine if the call does not access or only reads memory. bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); + return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } - void setOnlyReadsMemory(bool OnlyReadsMemory = true) { - if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly); - else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone); + void setOnlyReadsMemory() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadOnly)); } - /// @brief Determine if the call cannot return. - bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } - void setDoesNotReturn(bool DoesNotReturn = true) { - if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn); - else removeAttribute(~0, Attribute::NoReturn); + /// \brief Determine if the call cannot return. + bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } + void setDoesNotReturn() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoReturn)); } - /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } - void setDoesNotThrow(bool DoesNotThrow = true) { - if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind); - else removeAttribute(~0, Attribute::NoUnwind); + /// \brief Determine if the call cannot unwind. + bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } + void setDoesNotThrow() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoUnwind)); } - /// @brief Determine if the call returns a structure through first + /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { // Be friendly and also check the callee. - return paramHasAttr(1, Attribute::StructRet); + return paramHasAttr(1, Attributes::StructRet); } - /// @brief Determine if any call argument is an aggregate passed by value. + /// \brief Determine if any call argument is an aggregate passed by value. bool hasByValArgument() const { - return AttributeList.hasAttrSomewhere(Attribute::ByVal); + for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) + if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal)) + return true; + return false; } /// getCalledFunction - Return the function called, or null if this is an @@ -3141,7 +3128,6 @@ public: unsigned getNumSuccessors() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InvokeInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); } @@ -3221,7 +3207,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ResumeInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Resume; } @@ -3251,7 +3236,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) /// end of the block cannot be reached. /// class UnreachableInst : public TerminatorInst { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; protected: virtual UnreachableInst *clone_impl() const; @@ -3266,7 +3251,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UnreachableInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Unreachable; } @@ -3283,14 +3267,14 @@ private: // TruncInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a truncation of integer types. +/// \brief This class represents a truncation of integer types. class TruncInst : public CastInst { protected: - /// @brief Clone an identical TruncInst + /// \brief Clone an identical TruncInst virtual TruncInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics TruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The (smaller) type to truncate to @@ -3298,7 +3282,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics TruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The (smaller) type to truncate to @@ -3306,8 +3290,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const TruncInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Trunc; } @@ -3320,14 +3303,14 @@ public: // ZExtInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents zero extension of integer types. +/// \brief This class represents zero extension of integer types. class ZExtInst : public CastInst { protected: - /// @brief Clone an identical ZExtInst + /// \brief Clone an identical ZExtInst virtual ZExtInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics ZExtInst( Value *S, ///< The value to be zero extended Type *Ty, ///< The type to zero extend to @@ -3335,7 +3318,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end semantics. + /// \brief Constructor with insert-at-end semantics. ZExtInst( Value *S, ///< The value to be zero extended Type *Ty, ///< The type to zero extend to @@ -3343,8 +3326,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ZExtInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == ZExt; } @@ -3357,14 +3339,14 @@ public: // SExtInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a sign extension of integer types. +/// \brief This class represents a sign extension of integer types. class SExtInst : public CastInst { protected: - /// @brief Clone an identical SExtInst + /// \brief Clone an identical SExtInst virtual SExtInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics SExtInst( Value *S, ///< The value to be sign extended Type *Ty, ///< The type to sign extend to @@ -3372,7 +3354,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics SExtInst( Value *S, ///< The value to be sign extended Type *Ty, ///< The type to sign extend to @@ -3380,8 +3362,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SExtInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == SExt; } @@ -3394,14 +3375,14 @@ public: // FPTruncInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a truncation of floating point types. +/// \brief This class represents a truncation of floating point types. class FPTruncInst : public CastInst { protected: - /// @brief Clone an identical FPTruncInst + /// \brief Clone an identical FPTruncInst virtual FPTruncInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The type to truncate to @@ -3409,7 +3390,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The type to truncate to @@ -3417,8 +3398,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPTruncInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == FPTrunc; } @@ -3431,14 +3411,14 @@ public: // FPExtInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents an extension of floating point types. +/// \brief This class represents an extension of floating point types. class FPExtInst : public CastInst { protected: - /// @brief Clone an identical FPExtInst + /// \brief Clone an identical FPExtInst virtual FPExtInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics FPExtInst( Value *S, ///< The value to be extended Type *Ty, ///< The type to extend to @@ -3446,7 +3426,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics FPExtInst( Value *S, ///< The value to be extended Type *Ty, ///< The type to extend to @@ -3454,8 +3434,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPExtInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == FPExt; } @@ -3468,14 +3447,14 @@ public: // UIToFPInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast unsigned integer to floating point. +/// \brief This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { protected: - /// @brief Clone an identical UIToFPInst + /// \brief Clone an identical UIToFPInst virtual UIToFPInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics UIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3483,7 +3462,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics UIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3491,8 +3470,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UIToFPInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == UIToFP; } @@ -3505,14 +3483,14 @@ public: // SIToFPInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast from signed integer to floating point. +/// \brief This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { protected: - /// @brief Clone an identical SIToFPInst + /// \brief Clone an identical SIToFPInst virtual SIToFPInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics SIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3520,7 +3498,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics SIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3528,8 +3506,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SIToFPInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == SIToFP; } @@ -3542,14 +3519,14 @@ public: // FPToUIInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast from floating point to unsigned integer +/// \brief This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { protected: - /// @brief Clone an identical FPToUIInst + /// \brief Clone an identical FPToUIInst virtual FPToUIInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics FPToUIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3557,7 +3534,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics FPToUIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3565,8 +3542,7 @@ public: BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPToUIInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == FPToUI; } @@ -3579,14 +3555,14 @@ public: // FPToSIInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast from floating point to signed integer. +/// \brief This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { protected: - /// @brief Clone an identical FPToSIInst + /// \brief Clone an identical FPToSIInst virtual FPToSIInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics FPToSIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3594,7 +3570,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics FPToSIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3602,8 +3578,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPToSIInst *) { return true; } + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == FPToSI; } @@ -3616,10 +3591,10 @@ public: // IntToPtrInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast from an integer to a pointer. +/// \brief This class represents a cast from an integer to a pointer. class IntToPtrInst : public CastInst { public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics IntToPtrInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3627,7 +3602,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics IntToPtrInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3635,11 +3610,15 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical IntToPtrInst + /// \brief Clone an identical IntToPtrInst virtual IntToPtrInst *clone_impl() const; + /// \brief Returns the address space of this instruction's pointer type. + unsigned getAddressSpace() const { + return getType()->getPointerAddressSpace(); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntToPtrInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == IntToPtr; } @@ -3652,14 +3631,14 @@ public: // PtrToIntInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a cast from a pointer to an integer +/// \brief This class represents a cast from a pointer to an integer class PtrToIntInst : public CastInst { protected: - /// @brief Clone an identical PtrToIntInst + /// \brief Clone an identical PtrToIntInst virtual PtrToIntInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics PtrToIntInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3667,7 +3646,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics PtrToIntInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to @@ -3675,8 +3654,19 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + /// \brief Gets the pointer operand. + Value *getPointerOperand() { return getOperand(0); } + /// \brief Gets the pointer operand. + const Value *getPointerOperand() const { return getOperand(0); } + /// \brief Gets the operand index of the pointer operand. + static unsigned getPointerOperandIndex() { return 0U; } + + /// \brief Returns the address space of the pointer operand. + unsigned getPointerAddressSpace() const { + return getPointerOperand()->getType()->getPointerAddressSpace(); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const PtrToIntInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == PtrToInt; } @@ -3689,14 +3679,14 @@ public: // BitCastInst Class //===----------------------------------------------------------------------===// -/// @brief This class represents a no-op cast from one type to another. +/// \brief This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { protected: - /// @brief Clone an identical BitCastInst + /// \brief Clone an identical BitCastInst virtual BitCastInst *clone_impl() const; public: - /// @brief Constructor with insert-before-instruction semantics + /// \brief Constructor with insert-before-instruction semantics BitCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to @@ -3704,7 +3694,7 @@ public: Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); - /// @brief Constructor with insert-at-end-of-block semantics + /// \brief Constructor with insert-at-end-of-block semantics BitCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to @@ -3713,7 +3703,6 @@ public: ); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BitCastInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == BitCast; } diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 1cebdd2..9b2afd5 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -34,9 +34,9 @@ namespace llvm { /// functions. This allows the standard isa/dyncast/cast functionality to /// work with calls to intrinsic functions. class IntrinsicInst : public CallInst { - IntrinsicInst(); // DO NOT IMPLEMENT - IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT - void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT + IntrinsicInst() LLVM_DELETED_FUNCTION; + IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION; + void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION; public: /// getIntrinsicID - Return the intrinsic ID of this intrinsic. /// @@ -45,7 +45,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *) { return true; } static inline bool classof(const CallInst *I) { if (const Function *CF = I->getCalledFunction()) return CF->getIntrinsicID() != 0; @@ -62,7 +61,6 @@ namespace llvm { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgInfoIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::dbg_declare: @@ -86,7 +84,6 @@ namespace llvm { MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgDeclareInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_declare; } @@ -108,7 +105,6 @@ namespace llvm { MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgValueInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_value; } @@ -175,7 +171,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memcpy: @@ -205,7 +200,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemSetInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memset; } @@ -238,7 +232,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemTransferInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy || I->getIntrinsicID() == Intrinsic::memmove; @@ -254,7 +247,6 @@ namespace llvm { class MemCpyInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemCpyInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy; } @@ -268,7 +260,6 @@ namespace llvm { class MemMoveInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemMoveInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memmove; } @@ -277,6 +268,49 @@ namespace llvm { } }; + /// VAStartInst - This represents the llvm.va_start intrinsic. + /// + class VAStartInst : public IntrinsicInst { + public: + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::vastart; + } + static inline bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + + Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } + }; + + /// VAEndInst - This represents the llvm.va_end intrinsic. + /// + class VAEndInst : public IntrinsicInst { + public: + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::vaend; + } + static inline bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + + Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } + }; + + /// VACopyInst - This represents the llvm.va_copy intrinsic. + /// + class VACopyInst : public IntrinsicInst { + public: + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::vacopy; + } + static inline bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + + Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } + Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } + }; + } #endif diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index c350388..3108a8e 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -50,7 +50,7 @@ namespace Intrinsic { /// Intrinsic::getType(ID) - Return the function type for an intrinsic. /// FunctionType *getType(LLVMContext &Context, ID id, - ArrayRef<Type*> Tys = ArrayRef<Type*>()); + ArrayRef<Type*> Tys = ArrayRef<Type*>()); /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be /// overloaded. @@ -58,7 +58,7 @@ namespace Intrinsic { /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic. /// - AttrListPtr getAttributes(ID id); + AttrListPtr getAttributes(LLVMContext &C, ID id); /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function /// declaration for an intrinsic, and return it. diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index d1a0fee..2e1597f 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -121,15 +121,21 @@ def llvm_metadata_ty : LLVMType<MetadataVT>; // !{...} def llvm_x86mmx_ty : LLVMType<x86mmx>; def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i64>* +def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 +def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 +def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 +def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8 def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8 def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8 def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8 def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8 +def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16 def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16 def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16 def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16 def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16 +def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32 def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32 def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32 def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32 @@ -279,9 +285,9 @@ let Properties = [IntrNoMem] in { // NOTE: these are internal interfaces. def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; -def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>; +def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; -def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>; +def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; // Internal interface for object size checking def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty], @@ -339,7 +345,7 @@ let Properties = [IntrNoMem] in { } def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; -def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>; //===---------------- Generic Variable Attribute Intrinsics----------------===// // diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td index fa8034e..93b1ae1 100644 --- a/include/llvm/IntrinsicsARM.td +++ b/include/llvm/IntrinsicsARM.td @@ -16,147 +16,136 @@ // TLS let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">, - Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; -} + +def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">, + Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; //===----------------------------------------------------------------------===// // Saturating Arithmentic -let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, Commutative]>; - def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; -} +def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, Commutative]>; +def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; //===----------------------------------------------------------------------===// // Load and Store exclusive doubleword -let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, - llvm_ptr_ty], [IntrReadWriteArgMem]>; - def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty], - [IntrReadArgMem]>; -} +def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, + llvm_ptr_ty], [IntrReadWriteArgMem]>; +def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty], + [IntrReadArgMem]>; //===----------------------------------------------------------------------===// // VFP -let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">, - Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; - def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">, - Intrinsic<[], [llvm_i32_ty], []>; - def int_arm_vcvtr : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], - [IntrNoMem]>; - def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], - [IntrNoMem]>; -} +def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">, + Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; +def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">, + Intrinsic<[], [llvm_i32_ty], []>; +def int_arm_vcvtr : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], + [IntrNoMem]>; +def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], + [IntrNoMem]>; //===----------------------------------------------------------------------===// // Coprocessor -let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - // Move to coprocessor - def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; - def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; - - // Move from coprocessor - def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; - def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; - - // Coprocessor data processing - def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; - def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; - - // Move from two registers to coprocessor - def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; - def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; -} +// Move to coprocessor +def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + +// Move from coprocessor +def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; + +// Coprocessor data processing +def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + +// Move from two registers to coprocessor +def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; //===----------------------------------------------------------------------===// // Advanced SIMD (NEON) -let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". - - // The following classes do not correspond directly to GCC builtins. - class Neon_1Arg_Intrinsic - : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>; - class Neon_1Arg_Narrow_Intrinsic - : Intrinsic<[llvm_anyvector_ty], - [LLVMExtendedElementVectorType<0>], [IntrNoMem]>; - class Neon_2Arg_Intrinsic - : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; - class Neon_2Arg_Narrow_Intrinsic - : Intrinsic<[llvm_anyvector_ty], - [LLVMExtendedElementVectorType<0>, - LLVMExtendedElementVectorType<0>], - [IntrNoMem]>; - class Neon_2Arg_Long_Intrinsic - : Intrinsic<[llvm_anyvector_ty], - [LLVMTruncatedElementVectorType<0>, - LLVMTruncatedElementVectorType<0>], - [IntrNoMem]>; - class Neon_3Arg_Intrinsic - : Intrinsic<[llvm_anyvector_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; - class Neon_3Arg_Long_Intrinsic - : Intrinsic<[llvm_anyvector_ty], - [LLVMMatchType<0>, - LLVMTruncatedElementVectorType<0>, - LLVMTruncatedElementVectorType<0>], - [IntrNoMem]>; - class Neon_CvtFxToFP_Intrinsic - : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>; - class Neon_CvtFPToFx_Intrinsic - : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>; - - // The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors. - // Besides the table, VTBL has one other v8i8 argument and VTBX has two. - // Overall, the classes range from 2 to 6 v8i8 arguments. - class Neon_Tbl2Arg_Intrinsic - : Intrinsic<[llvm_v8i8_ty], - [llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; - class Neon_Tbl3Arg_Intrinsic - : Intrinsic<[llvm_v8i8_ty], - [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; - class Neon_Tbl4Arg_Intrinsic - : Intrinsic<[llvm_v8i8_ty], - [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], - [IntrNoMem]>; - class Neon_Tbl5Arg_Intrinsic - : Intrinsic<[llvm_v8i8_ty], - [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, - llvm_v8i8_ty], [IntrNoMem]>; - class Neon_Tbl6Arg_Intrinsic - : Intrinsic<[llvm_v8i8_ty], - [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, - llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; -} +// The following classes do not correspond directly to GCC builtins. +class Neon_1Arg_Intrinsic + : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>; +class Neon_1Arg_Narrow_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMExtendedElementVectorType<0>], [IntrNoMem]>; +class Neon_2Arg_Intrinsic + : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem]>; +class Neon_2Arg_Narrow_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMExtendedElementVectorType<0>, + LLVMExtendedElementVectorType<0>], + [IntrNoMem]>; +class Neon_2Arg_Long_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMTruncatedElementVectorType<0>, + LLVMTruncatedElementVectorType<0>], + [IntrNoMem]>; +class Neon_3Arg_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem]>; +class Neon_3Arg_Long_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, + LLVMTruncatedElementVectorType<0>, + LLVMTruncatedElementVectorType<0>], + [IntrNoMem]>; +class Neon_CvtFxToFP_Intrinsic + : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>; +class Neon_CvtFPToFx_Intrinsic + : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>; + +// The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors. +// Besides the table, VTBL has one other v8i8 argument and VTBX has two. +// Overall, the classes range from 2 to 6 v8i8 arguments. +class Neon_Tbl2Arg_Intrinsic + : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; +class Neon_Tbl3Arg_Intrinsic + : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; +class Neon_Tbl4Arg_Intrinsic + : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], + [IntrNoMem]>; +class Neon_Tbl5Arg_Intrinsic + : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, + llvm_v8i8_ty], [IntrNoMem]>; +class Neon_Tbl6Arg_Intrinsic + : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, + llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>; // Arithmetic ops @@ -209,20 +198,18 @@ def int_arm_neon_vsubhn : Neon_2Arg_Narrow_Intrinsic; def int_arm_neon_vrsubhn : Neon_2Arg_Narrow_Intrinsic; // Vector Absolute Compare. -let TargetPrefix = "arm" in { - def int_arm_neon_vacged : Intrinsic<[llvm_v2i32_ty], - [llvm_v2f32_ty, llvm_v2f32_ty], - [IntrNoMem]>; - def int_arm_neon_vacgeq : Intrinsic<[llvm_v4i32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_arm_neon_vacgtd : Intrinsic<[llvm_v2i32_ty], - [llvm_v2f32_ty, llvm_v2f32_ty], - [IntrNoMem]>; - def int_arm_neon_vacgtq : Intrinsic<[llvm_v4i32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; -} +def int_arm_neon_vacged : Intrinsic<[llvm_v2i32_ty], + [llvm_v2f32_ty, llvm_v2f32_ty], + [IntrNoMem]>; +def int_arm_neon_vacgeq : Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], + [IntrNoMem]>; +def int_arm_neon_vacgtd : Intrinsic<[llvm_v2i32_ty], + [llvm_v2f32_ty, llvm_v2f32_ty], + [IntrNoMem]>; +def int_arm_neon_vacgtq : Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], + [IntrNoMem]>; // Vector Absolute Differences. def int_arm_neon_vabds : Neon_2Arg_Intrinsic; @@ -235,24 +222,20 @@ def int_arm_neon_vpadd : Neon_2Arg_Intrinsic; // Note: This is different than the other "long" NEON intrinsics because // the result vector has half as many elements as the source vector. // The source and destination vector types must be specified separately. -let TargetPrefix = "arm" in { - def int_arm_neon_vpaddls : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], - [IntrNoMem]>; - def int_arm_neon_vpaddlu : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], - [IntrNoMem]>; -} +def int_arm_neon_vpaddls : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], + [IntrNoMem]>; +def int_arm_neon_vpaddlu : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], + [IntrNoMem]>; // Vector Pairwise Add and Accumulate Long. // Note: This is similar to vpaddl but the destination vector also appears // as the first argument. -let TargetPrefix = "arm" in { - def int_arm_neon_vpadals : Intrinsic<[llvm_anyvector_ty], - [LLVMMatchType<0>, llvm_anyvector_ty], - [IntrNoMem]>; - def int_arm_neon_vpadalu : Intrinsic<[llvm_anyvector_ty], - [LLVMMatchType<0>, llvm_anyvector_ty], - [IntrNoMem]>; -} +def int_arm_neon_vpadals : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty], + [IntrNoMem]>; +def int_arm_neon_vpadalu : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty], + [IntrNoMem]>; // Vector Pairwise Maximum and Minimum. def int_arm_neon_vpmaxs : Neon_2Arg_Intrinsic; @@ -364,79 +347,83 @@ def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic; def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic; def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic; -let TargetPrefix = "arm" in { - - // De-interleaving vector loads from N-element structures. - // Source operands are the address and alignment. - def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty], - [llvm_ptr_ty, llvm_i32_ty], - [IntrReadArgMem]>; - def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], - [IntrReadArgMem]>; - def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, - LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], - [IntrReadArgMem]>; - def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], - [IntrReadArgMem]>; - - // Vector load N-element structure to one lane. - // Source operands are: the address, the N input vectors (since only one - // lane is assigned), the lane number, and the alignment. - def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty, - llvm_i32_ty], [IntrReadArgMem]>; - def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, - LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>, - llvm_i32_ty, llvm_i32_ty], - [IntrReadArgMem]>; - def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty, - llvm_i32_ty], [IntrReadArgMem]>; - - // Interleaving vector stores from N-element structures. - // Source operands are: the address, the N vectors, and the alignment. - def int_arm_neon_vst1 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - llvm_i32_ty], [IntrReadWriteArgMem]>; - def int_arm_neon_vst2 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, llvm_i32_ty], - [IntrReadWriteArgMem]>; - def int_arm_neon_vst3 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - llvm_i32_ty], [IntrReadWriteArgMem]>; - def int_arm_neon_vst4 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty], - [IntrReadWriteArgMem]>; - - // Vector store N-element structure from one lane. - // Source operands are: the address, the N vectors, the lane number, and - // the alignment. - def int_arm_neon_vst2lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, llvm_i32_ty, - llvm_i32_ty], [IntrReadWriteArgMem]>; - def int_arm_neon_vst3lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - llvm_i32_ty, llvm_i32_ty], - [IntrReadWriteArgMem]>; - def int_arm_neon_vst4lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty, - llvm_i32_ty], [IntrReadWriteArgMem]>; -} +// De-interleaving vector loads from N-element structures. +// Source operands are the address and alignment. +def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty], + [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>; +def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], + [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>; +def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>], + [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>; +def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>, LLVMMatchType<0>], + [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>; + +// Vector load N-element structure to one lane. +// Source operands are: the address, the N input vectors (since only one +// lane is assigned), the lane number, and the alignment. +def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], + [llvm_ptr_ty, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_i32_ty, + llvm_i32_ty], [IntrReadArgMem]>; +def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>], + [llvm_ptr_ty, LLVMMatchType<0>, + LLVMMatchType<0>, LLVMMatchType<0>, + llvm_i32_ty, llvm_i32_ty], + [IntrReadArgMem]>; +def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>, LLVMMatchType<0>], + [llvm_ptr_ty, LLVMMatchType<0>, + LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_i32_ty, + llvm_i32_ty], [IntrReadArgMem]>; + +// Interleaving vector stores from N-element structures. +// Source operands are: the address, the N vectors, and the alignment. +def int_arm_neon_vst1 : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + llvm_i32_ty], [IntrReadWriteArgMem]>; +def int_arm_neon_vst2 : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, llvm_i32_ty], + [IntrReadWriteArgMem]>; +def int_arm_neon_vst3 : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, LLVMMatchType<0>, + llvm_i32_ty], [IntrReadWriteArgMem]>; +def int_arm_neon_vst4 : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_i32_ty], + [IntrReadWriteArgMem]>; + +// Vector store N-element structure from one lane. +// Source operands are: the address, the N vectors, the lane number, and +// the alignment. +def int_arm_neon_vst2lane : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, llvm_i32_ty, + llvm_i32_ty], [IntrReadWriteArgMem]>; +def int_arm_neon_vst3lane : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, LLVMMatchType<0>, + llvm_i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; +def int_arm_neon_vst4lane : Intrinsic<[], + [llvm_ptr_ty, llvm_anyvector_ty, + LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_i32_ty, + llvm_i32_ty], [IntrReadWriteArgMem]>; + +// Vector bitwise select. +def int_arm_neon_vbsl : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem]>; + +} // end TargetPrefix diff --git a/include/llvm/IntrinsicsMips.td b/include/llvm/IntrinsicsMips.td index 4375ac2..e40e162 100644 --- a/include/llvm/IntrinsicsMips.td +++ b/include/llvm/IntrinsicsMips.td @@ -14,11 +14,15 @@ //===----------------------------------------------------------------------===// // MIPS DSP data types def mips_v2q15_ty: LLVMType<v2i16>; +def mips_v4q7_ty: LLVMType<v4i8>; def mips_q31_ty: LLVMType<i32>; let TargetPrefix = "mips" in { // All intrinsics start with "llvm.mips.". //===----------------------------------------------------------------------===// +// MIPS DSP Rev 1 + +//===----------------------------------------------------------------------===// // Addition/subtraction def int_mips_addu_qb : GCCBuiltin<"__builtin_mips_addu_qb">, @@ -261,4 +265,125 @@ def int_mips_lhx: GCCBuiltin<"__builtin_mips_lhx">, Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_mips_lwx: GCCBuiltin<"__builtin_mips_lwx">, Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>; + +//===----------------------------------------------------------------------===// +// MIPS DSP Rev 2 + +def int_mips_absq_s_qb: GCCBuiltin<"__builtin_mips_absq_s_qb">, + Intrinsic<[mips_v4q7_ty], [mips_v4q7_ty], []>; + +def int_mips_addqh_ph: GCCBuiltin<"__builtin_mips_addqh_ph">, + Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], + [IntrNoMem, Commutative]>; +def int_mips_addqh_r_ph: GCCBuiltin<"__builtin_mips_addqh_r_ph">, + Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], + [IntrNoMem, Commutative]>; +def int_mips_addqh_w: GCCBuiltin<"__builtin_mips_addqh_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], + [IntrNoMem, Commutative]>; +def int_mips_addqh_r_w: GCCBuiltin<"__builtin_mips_addqh_r_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], + [IntrNoMem, Commutative]>; + +def int_mips_addu_ph: GCCBuiltin<"__builtin_mips_addu_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>; +def int_mips_addu_s_ph: GCCBuiltin<"__builtin_mips_addu_s_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>; + +def int_mips_adduh_qb: GCCBuiltin<"__builtin_mips_adduh_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], + [IntrNoMem, Commutative]>; +def int_mips_adduh_r_qb: GCCBuiltin<"__builtin_mips_adduh_r_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], + [IntrNoMem, Commutative]>; + +def int_mips_append: GCCBuiltin<"__builtin_mips_append">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + +def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">, + Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; +def int_mips_cmpgdu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgdu_lt_qb">, + Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; +def int_mips_cmpgdu_le_qb: GCCBuiltin<"__builtin_mips_cmpgdu_le_qb">, + Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; + +def int_mips_dpa_w_ph: GCCBuiltin<"__builtin_mips_dpa_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem]>; +def int_mips_dps_w_ph: GCCBuiltin<"__builtin_mips_dps_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem]>; + +def int_mips_dpaqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_s_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>; +def int_mips_dpaqx_sa_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_sa_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>; +def int_mips_dpax_w_ph: GCCBuiltin<"__builtin_mips_dpax_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem]>; +def int_mips_dpsx_w_ph: GCCBuiltin<"__builtin_mips_dpsx_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem]>; +def int_mips_dpsqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpsqx_s_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>; +def int_mips_dpsqx_sa_w_ph: GCCBuiltin<"__builtin_mips_dpsqx_sa_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>; + +def int_mips_mul_ph: GCCBuiltin<"__builtin_mips_mul_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>; +def int_mips_mul_s_ph: GCCBuiltin<"__builtin_mips_mul_s_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>; + +def int_mips_mulq_rs_w: GCCBuiltin<"__builtin_mips_mulq_rs_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>; +def int_mips_mulq_s_ph: GCCBuiltin<"__builtin_mips_mulq_s_ph">, + Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>; +def int_mips_mulq_s_w: GCCBuiltin<"__builtin_mips_mulq_s_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>; +def int_mips_mulsa_w_ph: GCCBuiltin<"__builtin_mips_mulsa_w_ph">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem]>; + +def int_mips_precr_qb_ph: GCCBuiltin<"__builtin_mips_precr_qb_ph">, + Intrinsic<[llvm_v4i8_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>; +def int_mips_precr_sra_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_ph_w">, + Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_mips_precr_sra_r_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_r_ph_w">, + Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + +def int_mips_prepend: GCCBuiltin<"__builtin_mips_prepend">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + +def int_mips_shra_qb: GCCBuiltin<"__builtin_mips_shra_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_shra_r_qb: GCCBuiltin<"__builtin_mips_shra_r_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_shrl_ph: GCCBuiltin<"__builtin_mips_shrl_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_i32_ty], [IntrNoMem]>; + +def int_mips_subqh_ph: GCCBuiltin<"__builtin_mips_subqh_ph">, + Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>; +def int_mips_subqh_r_ph: GCCBuiltin<"__builtin_mips_subqh_r_ph">, + Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>; +def int_mips_subqh_w: GCCBuiltin<"__builtin_mips_subqh_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>; +def int_mips_subqh_r_w: GCCBuiltin<"__builtin_mips_subqh_r_w">, + Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>; + +def int_mips_subu_ph: GCCBuiltin<"__builtin_mips_subu_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>; +def int_mips_subu_s_ph: GCCBuiltin<"__builtin_mips_subu_s_ph">, + Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>; + +def int_mips_subuh_qb: GCCBuiltin<"__builtin_mips_subuh_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>; +def int_mips_subuh_r_qb: GCCBuiltin<"__builtin_mips_subuh_r_qb">, + Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>; } diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index e8039f2..d2463c0 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -219,7 +219,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4f32_ty], []>; + llvm_v4f32_ty], [IntrReadWriteArgMem]>; } // Cacheability support ops @@ -502,13 +502,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">, Intrinsic<[], [llvm_ptr_ty, - llvm_v2f64_ty], []>; + llvm_v2f64_ty], [IntrReadWriteArgMem]>; def int_x86_sse2_storeu_dq : GCCBuiltin<"__builtin_ia32_storedqu">, Intrinsic<[], [llvm_ptr_ty, - llvm_v16i8_ty], []>; + llvm_v16i8_ty], [IntrReadWriteArgMem]>; def int_x86_sse2_storel_dq : GCCBuiltin<"__builtin_ia32_storelv4si">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4i32_ty], []>; + llvm_v4i32_ty], [IntrReadWriteArgMem]>; } // Misc. @@ -1270,19 +1270,19 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_vbroadcast_ss : GCCBuiltin<"__builtin_ia32_vbroadcastss">, - Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx_vbroadcast_sd_256 : GCCBuiltin<"__builtin_ia32_vbroadcastsd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx_vbroadcast_ss_256 : GCCBuiltin<"__builtin_ia32_vbroadcastss256">, - Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx_vbroadcastf128_pd_256 : GCCBuiltin<"__builtin_ia32_vbroadcastf128_pd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx_vbroadcastf128_ps_256 : GCCBuiltin<"__builtin_ia32_vbroadcastf128_ps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; } // SIMD load ops @@ -1294,41 +1294,45 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // SIMD store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_storeu_pd_256 : GCCBuiltin<"__builtin_ia32_storeupd256">, - Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>; def int_x86_avx_storeu_ps_256 : GCCBuiltin<"__builtin_ia32_storeups256">, - Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>; def int_x86_avx_storeu_dq_256 : GCCBuiltin<"__builtin_ia32_storedqu256">, - Intrinsic<[], [llvm_ptr_ty, llvm_v32i8_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v32i8_ty], [IntrReadWriteArgMem]>; } // Conditional load ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_maskload_pd : GCCBuiltin<"__builtin_ia32_maskloadpd">, - Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2f64_ty], [IntrReadMem]>; + Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2f64_ty], + [IntrReadArgMem]>; def int_x86_avx_maskload_ps : GCCBuiltin<"__builtin_ia32_maskloadps">, - Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4f32_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4f32_ty], + [IntrReadArgMem]>; def int_x86_avx_maskload_pd_256 : GCCBuiltin<"__builtin_ia32_maskloadpd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4f64_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4f64_ty], + [IntrReadArgMem]>; def int_x86_avx_maskload_ps_256 : GCCBuiltin<"__builtin_ia32_maskloadps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty], [IntrReadMem]>; + Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty], + [IntrReadArgMem]>; } // Conditional store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_maskstore_pd : GCCBuiltin<"__builtin_ia32_maskstorepd">, Intrinsic<[], [llvm_ptr_ty, - llvm_v2f64_ty, llvm_v2f64_ty], []>; + llvm_v2f64_ty, llvm_v2f64_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_ps : GCCBuiltin<"__builtin_ia32_maskstoreps">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4f32_ty, llvm_v4f32_ty], []>; + llvm_v4f32_ty, llvm_v4f32_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_pd_256 : GCCBuiltin<"__builtin_ia32_maskstorepd256">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4f64_ty, llvm_v4f64_ty], []>; + llvm_v4f64_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_ps_256 : GCCBuiltin<"__builtin_ia32_maskstoreps256">, Intrinsic<[], [llvm_ptr_ty, - llvm_v8f32_ty, llvm_v8f32_ty], []>; + llvm_v8f32_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>; } //===----------------------------------------------------------------------===// @@ -1632,7 +1636,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; def int_x86_avx2_vbroadcasti128 : GCCBuiltin<"__builtin_ia32_vbroadcastsi256">, - Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx2_pbroadcastb_128 : GCCBuiltin<"__builtin_ia32_pbroadcastb128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; @@ -1685,27 +1689,35 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Conditional load ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_maskload_d : GCCBuiltin<"__builtin_ia32_maskloadd">, - Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_v4i32_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_v4i32_ty], + [IntrReadArgMem]>; def int_x86_avx2_maskload_q : GCCBuiltin<"__builtin_ia32_maskloadq">, - Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_v2i64_ty], [IntrReadMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_v2i64_ty], + [IntrReadArgMem]>; def int_x86_avx2_maskload_d_256 : GCCBuiltin<"__builtin_ia32_maskloadd256">, - Intrinsic<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_v8i32_ty], [IntrReadMem]>; + Intrinsic<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_v8i32_ty], + [IntrReadArgMem]>; def int_x86_avx2_maskload_q_256 : GCCBuiltin<"__builtin_ia32_maskloadq256">, - Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_v4i64_ty], [IntrReadMem]>; + Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_v4i64_ty], + [IntrReadArgMem]>; } // Conditional store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_maskstore_d : GCCBuiltin<"__builtin_ia32_maskstored">, - Intrinsic<[], [llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty], + [IntrReadWriteArgMem]>; def int_x86_avx2_maskstore_q : GCCBuiltin<"__builtin_ia32_maskstoreq">, - Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty], + [IntrReadWriteArgMem]>; def int_x86_avx2_maskstore_d_256 : GCCBuiltin<"__builtin_ia32_maskstored256">, - Intrinsic<[], [llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty], + [IntrReadWriteArgMem]>; def int_x86_avx2_maskstore_q_256 : GCCBuiltin<"__builtin_ia32_maskstoreq256">, - Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty], []>; + Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty], + [IntrReadWriteArgMem]>; } // Variable bit shift ops @@ -2547,3 +2559,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; } + +//===----------------------------------------------------------------------===// +// RTM intrinsics. Transactional Memory support. + +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_xbegin : GCCBuiltin<"__builtin_ia32_xbegin">, + Intrinsic<[llvm_i32_ty], [], []>; + def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">, + Intrinsic<[], [], []>; + def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">, + Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>; +} diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index a8306a9..5903e2e 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -15,6 +15,8 @@ #ifndef LLVM_LLVMCONTEXT_H #define LLVM_LLVMCONTEXT_H +#include "llvm/Support/Compiler.h" + namespace llvm { class LLVMContextImpl; @@ -43,7 +45,8 @@ public: MD_tbaa = 1, // "tbaa" MD_prof = 2, // "prof" MD_fpmath = 3, // "fpmath" - MD_range = 4 // "range" + MD_range = 4, // "range" + MD_tbaa_struct = 5 // "tbaa.struct" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. @@ -87,9 +90,8 @@ public: void emitError(const Twine &ErrorStr); private: - // DO NOT IMPLEMENT - LLVMContext(LLVMContext&); - void operator=(LLVMContext&); + LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION; + void operator=(LLVMContext&) LLVM_DELETED_FUNCTION; /// addModule - Register a module as being instantiated in this context. If /// the context is deleted, the module will be deleted as well. diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 697c94c..806e4b3 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -60,10 +60,12 @@ namespace { (void) llvm::createCFGSimplificationPass(); (void) llvm::createConstantMergePass(); (void) llvm::createConstantPropagationPass(); + (void) llvm::createCostModelAnalysisPass(); (void) llvm::createDeadArgEliminationPass(); (void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadStoreEliminationPass(); + (void) llvm::createDependenceAnalysisPass(); (void) llvm::createDomOnlyPrinterPass(); (void) llvm::createDomPrinterPass(); (void) llvm::createDomOnlyViewerPass(); @@ -81,11 +83,10 @@ namespace { (void) llvm::createIPSCCPPass(); (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); - (void) llvm::createInternalizePass(false); + (void) llvm::createInternalizePass(); (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLazyValueInfoPass(); - (void) llvm::createLoopDependenceAnalysisPass(); (void) llvm::createLoopExtractorPass(); (void) llvm::createLoopSimplifyPass(); (void) llvm::createLoopStrengthReducePass(); @@ -107,6 +108,7 @@ namespace { (void) llvm::createProfileVerifierPass(); (void) llvm::createPathProfileVerifierPass(); (void) llvm::createProfileLoaderPass(); + (void) llvm::createProfileMetadataLoaderPass(); (void) llvm::createPathProfileLoaderPass(); (void) llvm::createPromoteMemoryToRegisterPass(); (void) llvm::createDemoteRegisterToMemoryPass(); @@ -140,6 +142,7 @@ namespace { (void) llvm::createLoopDeletionPass(); (void) llvm::createPostDomTree(); (void) llvm::createInstructionNamerPass(); + (void) llvm::createMetaRenamerPass(); (void) llvm::createFunctionAttrsPass(); (void) llvm::createMergeFunctionsPass(); (void) llvm::createPrintModulePass(0); @@ -153,6 +156,7 @@ namespace { (void) llvm::createCorrelatedValuePropagationPass(); (void) llvm::createMemDepPrinter(); (void) llvm::createInstructionSimplifierPass(); + (void) llvm::createLoopVectorizePass(); (void) llvm::createBBVectorizePass(); (void)new llvm::IntervalPartition(); diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 05e6286..72ed1a3 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -30,12 +30,13 @@ class raw_ostream; /// MCAsmBackend - Generic interface to target specific assembler backends. class MCAsmBackend { - MCAsmBackend(const MCAsmBackend &); // DO NOT IMPLEMENT - void operator=(const MCAsmBackend &); // DO NOT IMPLEMENT + MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION; + void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. MCAsmBackend(); unsigned HasReliableSymbolDifference : 1; + unsigned HasDataInCodeSupport : 1; public: virtual ~MCAsmBackend(); @@ -65,6 +66,12 @@ public: return HasReliableSymbolDifference; } + /// hasDataInCodeSupport - Check whether this target implements data-in-code + /// markers. If not, data region directives will be ignored. + bool hasDataInCodeSupport() const { + return HasDataInCodeSupport; + } + /// doesSectionRequireSymbols - Check whether the given section requires that /// all symbols (even temporaries) have symbol table entries. virtual bool doesSectionRequireSymbols(const MCSection &Section) const { @@ -99,7 +106,7 @@ public: /// @} - /// applyFixup - Apply the \arg Value for given \arg Fixup into the provided + /// applyFixup - Apply the \p Value for given \p Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, @@ -126,13 +133,20 @@ public: /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. /// - /// \param Inst - The instruction to relax, which may be the same as the + /// \param Inst The instruction to relax, which may be the same as the /// output. - /// \parm Res [output] - On return, the relaxed instruction. + /// \param [out] Res On return, the relaxed instruction. virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; /// @} + /// getMinimumNopSize - Returns the minimum size of a nop in bytes on this + /// target. The assembler will use this to emit excess padding in situations + /// where the padding required for simple alignment would be less than the + /// minimum nop size. + /// + virtual unsigned getMinimumNopSize() const { return 1; } + /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given /// output. If the target cannot generate such a sequence, it should return an /// error. diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 9f5230b..97aad71 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -33,7 +33,7 @@ namespace llvm { } namespace LCOMM { - enum LCOMMType { None, NoAlignment, ByteAlignment }; + enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment }; } /// MCAsmInfo - This class is intended to be used as a base class for asm @@ -247,14 +247,14 @@ namespace llvm { /// .long a - b bool HasAggressiveSymbolFolding; // Defaults to true. - /// LCOMMDirectiveType - Describes if the target supports the .lcomm - /// directive and whether it has an alignment parameter. - LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None. - - /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional + /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional /// alignment is to be specified in bytes instead of log2(n). bool COMMDirectiveAlignmentIsInBytes; // Defaults to true; + /// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the + /// target supports an alignment argument and how it is interpreted. + LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment. + /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. @@ -496,13 +496,13 @@ namespace llvm { bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } - LCOMM::LCOMMType getLCOMMDirectiveType() const { - return LCOMMDirectiveType; - } - bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { return COMMDirectiveAlignmentIsInBytes; } + LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const { + return LCOMMDirectiveAlignmentType; + } + bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } bool hasSymbolResolver() const { return HasSymbolResolver; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index b7b2d66..5771415 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -40,8 +40,8 @@ class MCAsmBackend; class MCFragment : public ilist_node<MCFragment> { friend class MCAsmLayout; - MCFragment(const MCFragment&); // DO NOT IMPLEMENT - void operator=(const MCFragment&); // DO NOT IMPLEMENT + MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; + void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; public: enum FragmentType { @@ -99,8 +99,6 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - static bool classof(const MCFragment *O) { return true; } - void dump(); }; @@ -151,7 +149,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } - static bool classof(const MCDataFragment *) { return true; } }; // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as @@ -176,7 +173,7 @@ public: typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; public: - MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) + MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) : MCFragment(FT_Inst, SD), Inst(_Inst) { } @@ -191,7 +188,7 @@ public: MCInst &getInst() { return Inst; } const MCInst &getInst() const { return Inst; } - void setInst(MCInst Value) { Inst = Value; } + void setInst(const MCInst& Value) { Inst = Value; } /// @} /// @name Fixup Access @@ -213,7 +210,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Inst; } - static bool classof(const MCInstFragment *) { return true; } }; class MCAlignFragment : public MCFragment { @@ -225,7 +221,7 @@ class MCAlignFragment : public MCFragment { /// Value - Value to use for filling padding bytes. int64_t Value; - /// ValueSize - The size of the integer (in bytes) of \arg Value. + /// ValueSize - The size of the integer (in bytes) of \p Value. unsigned ValueSize; /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment @@ -263,7 +259,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Align; } - static bool classof(const MCAlignFragment *) { return true; } }; class MCFillFragment : public MCFragment { @@ -272,7 +267,7 @@ class MCFillFragment : public MCFragment { /// Value - Value to use for filling bytes. int64_t Value; - /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if + /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if /// this is a virtual fill fragment. unsigned ValueSize; @@ -302,7 +297,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Fill; } - static bool classof(const MCFillFragment *) { return true; } }; class MCOrgFragment : public MCFragment { @@ -331,7 +325,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Org; } - static bool classof(const MCOrgFragment *) { return true; } }; class MCLEBFragment : public MCFragment { @@ -364,7 +357,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_LEB; } - static bool classof(const MCLEBFragment *) { return true; } }; class MCDwarfLineAddrFragment : public MCFragment { @@ -401,7 +393,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Dwarf; } - static bool classof(const MCDwarfLineAddrFragment *) { return true; } }; class MCDwarfCallFrameFragment : public MCFragment { @@ -431,7 +422,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_DwarfFrame; } - static bool classof(const MCDwarfCallFrameFragment *) { return true; } }; // FIXME: Should this be a separate class, or just merged into MCSection? Since @@ -440,8 +430,8 @@ public: class MCSectionData : public ilist_node<MCSectionData> { friend class MCAsmLayout; - MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT - void operator=(const MCSectionData&); // DO NOT IMPLEMENT + MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION; + void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION; public: typedef iplist<MCFragment> FragmentListType; @@ -683,8 +673,8 @@ public: typedef std::vector<DataRegionData>::iterator data_region_iterator; private: - MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT - void operator=(const MCAssembler&); // DO NOT IMPLEMENT + MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; + void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; MCContext &Context; @@ -738,7 +728,7 @@ private: /// \param Value [out] On return, the value of the fixup as currently laid /// out. /// \return Whether the fixup value was fully resolved. This is true if the - /// \arg Value result is fixed, otherwise the value may change due to + /// \p Value result is fixed, otherwise the value may change due to /// relocation. bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, @@ -775,7 +765,7 @@ private: public: /// Compute the effective fragment size assuming it is laid out at the given - /// \arg SectionAddress and \arg FragmentOffset. + /// \p SectionAddress and \p FragmentOffset. uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; @@ -804,7 +794,7 @@ public: public: /// Construct a new assembler instance. /// - /// \arg OS - The stream to output to. + /// \param OS The stream to output to. // // FIXME: How are we going to parameterize this? Two obvious options are stay // concrete and require clients to pass in a target like object. The other @@ -824,7 +814,7 @@ public: MCObjectWriter &getWriter() const { return Writer; } /// Finish - Do final processing and write the object to the output stream. - /// \arg Writer is used for custom object writer (as the MCJIT does), + /// \p Writer is used for custom object writer (as the MCJIT does), /// if not specified it is automatically created from backend. void Finish(); diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 934ef69..0574890 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -10,6 +10,8 @@ #ifndef LLVM_MC_MCCODEEMITTER_H #define LLVM_MC_MCCODEEMITTER_H +#include "llvm/Support/Compiler.h" + namespace llvm { class MCFixup; class MCInst; @@ -19,16 +21,16 @@ template<typename T> class SmallVectorImpl; /// MCCodeEmitter - Generic instruction encoding interface. class MCCodeEmitter { private: - MCCodeEmitter(const MCCodeEmitter &); // DO NOT IMPLEMENT - void operator=(const MCCodeEmitter &); // DO NOT IMPLEMENT + MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; + void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. MCCodeEmitter(); public: virtual ~MCCodeEmitter(); - /// EncodeInstruction - Encode the given \arg Inst to bytes on the output - /// stream \arg OS. + /// EncodeInstruction - Encode the given \p Inst to bytes on the output + /// stream \p OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const = 0; }; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 59545d3..5a8830c 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -40,8 +40,8 @@ namespace llvm { /// of the sections that it creates. /// class MCContext { - MCContext(const MCContext&); // DO NOT IMPLEMENT - MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT + MCContext(const MCContext&) LLVM_DELETED_FUNCTION; + MCContext &operator=(const MCContext&) LLVM_DELETED_FUNCTION; public: typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable; private: @@ -183,6 +183,7 @@ namespace llvm { /// LookupSymbol - Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(StringRef Name) const; + MCSymbol *LookupSymbol(const Twine &Name) const; /// getSymbols - Get a reference for the symbol table for clients that /// want to, for example, iterate over all symbols. 'const' because we diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index fdb7ab2..8fc437f 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -19,6 +19,7 @@ #include "llvm/MC/MachineLocation.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/Compiler.h" #include <vector> namespace llvm { @@ -48,8 +49,8 @@ namespace llvm { MCDwarfFile(StringRef name, unsigned dirIndex) : Name(name), DirIndex(dirIndex) {} - MCDwarfFile(const MCDwarfFile&); // DO NOT IMPLEMENT - void operator=(const MCDwarfFile&); // DO NOT IMPLEMENT + MCDwarfFile(const MCDwarfFile&) LLVM_DELETED_FUNCTION; + void operator=(const MCDwarfFile&) LLVM_DELETED_FUNCTION; public: /// getName - Get the base name of this MCDwarfFile. StringRef getName() const { return Name; } @@ -58,7 +59,7 @@ namespace llvm { unsigned getDirIndex() const { return DirIndex; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. @@ -177,8 +178,8 @@ namespace llvm { class MCLineSection { private: - MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT - void operator=(const MCLineSection&); // DO NOT IMPLEMENT + MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION; + void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION; public: // Constructor to create an MCLineSection with an empty MCLineEntries diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index abbe188..38cdc72 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -85,6 +85,9 @@ public: const MCFragment &F, const MCFixup &Fixup, bool IsPCRel) const; + virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const; virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); @@ -93,9 +96,9 @@ public: /// @name Accessors /// @{ - uint8_t getOSABI() { return OSABI; } - uint16_t getEMachine() { return EMachine; } - bool hasRelocationAddend() { return HasRelocationAddend; } + uint8_t getOSABI() const { return OSABI; } + uint16_t getEMachine() const { return EMachine; } + bool hasRelocationAddend() const { return HasRelocationAddend; } bool is64Bit() const { return Is64Bit; } bool isN64() const { return IsN64; } /// @} diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index aa62eb2..00eef27 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -41,8 +41,8 @@ public: private: ExprKind Kind; - MCExpr(const MCExpr&); // DO NOT IMPLEMENT - void operator=(const MCExpr&); // DO NOT IMPLEMENT + MCExpr(const MCExpr&) LLVM_DELETED_FUNCTION; + void operator=(const MCExpr&) LLVM_DELETED_FUNCTION; bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, @@ -78,11 +78,11 @@ public: /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// @result - True on success. + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + const SectionAddrMap &Addrs) const; bool EvaluateAsAbsolute(int64_t &Res) const; bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, - const SectionAddrMap &Addrs) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). @@ -99,8 +99,6 @@ public: const MCSection *FindAssociatedSection() const; /// @} - - static bool classof(const MCExpr *) { return true; } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { @@ -132,7 +130,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Constant; } - static bool classof(const MCConstantExpr *) { return true; } }; /// MCSymbolRefExpr - Represent a reference to a symbol from inside an @@ -170,8 +167,10 @@ public: VK_ARM_TPOFF, VK_ARM_GOTTPOFF, VK_ARM_TARGET1, + VK_ARM_TARGET2, - VK_PPC_TOC, + VK_PPC_TOC, // TOC base + VK_PPC_TOC_ENTRY, // TOC entry VK_PPC_DARWIN_HA16, // ha16(symbol) VK_PPC_DARWIN_LO16, // lo16(symbol) VK_PPC_GAS_HA16, // symbol@ha @@ -247,7 +246,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::SymbolRef; } - static bool classof(const MCSymbolRefExpr *) { return true; } }; /// MCUnaryExpr - Unary assembler expressions. @@ -301,7 +299,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Unary; } - static bool classof(const MCUnaryExpr *) { return true; } }; /// MCBinaryExpr - Binary assembler expressions. @@ -436,7 +433,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Binary; } - static bool classof(const MCBinaryExpr *) { return true; } }; /// MCTargetExpr - This is an extension point for target-specific MCExpr @@ -445,7 +441,7 @@ public: /// NOTE: All subclasses are required to have trivial destructors because /// MCExprs are bump pointer allocated and not destructed. class MCTargetExpr : public MCExpr { - virtual void Anchor(); + virtual void anchor(); protected: MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} @@ -460,7 +456,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; } - static bool classof(const MCTargetExpr *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 397a37d..e91c6a2 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -182,7 +182,7 @@ public: void dump() const; /// \brief Dump the MCInst as prettily as possible using the additional MC - /// structures, if given. Operators are separated by the \arg Separator + /// structures, if given. Operators are separated by the \p Separator /// string. void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0, const MCInstPrinter *Printer = 0, diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 3c4f28b..3b9420a 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -33,12 +33,16 @@ protected: /// The current set of available features. unsigned AvailableFeatures; + /// True if we are printing marked up assembly. + bool UseMarkup; + /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) - : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {} + : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), + UseMarkup(0) {} virtual ~MCInstPrinter(); @@ -59,6 +63,13 @@ public: unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } + + bool getUseMarkup() const { return UseMarkup; } + void setUseMarkup(bool Value) { UseMarkup = Value; } + + /// Utility functions to make adding mark ups simpler. + StringRef markup(StringRef s) const; + StringRef markup(StringRef a, StringRef b) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index dbf16d8..02383f8 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -1,4 +1,4 @@ -//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===// +//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h index 727520d..f531de8 100644 --- a/include/llvm/MC/MCLabel.h +++ b/include/llvm/MC/MCLabel.h @@ -14,6 +14,8 @@ #ifndef LLVM_MC_MCLABEL_H #define LLVM_MC_MCLABEL_H +#include "llvm/Support/Compiler.h" + namespace llvm { class MCContext; class raw_ostream; @@ -30,8 +32,8 @@ namespace llvm { MCLabel(unsigned instance) : Instance(instance) {} - MCLabel(const MCLabel&); // DO NOT IMPLEMENT - void operator=(const MCLabel&); // DO NOT IMPLEMENT + MCLabel(const MCLabel&) LLVM_DELETED_FUNCTION; + void operator=(const MCLabel&) LLVM_DELETED_FUNCTION; public: /// getInstance - Get the current instance of this Directional Local Label. unsigned getInstance() const { return Instance; } @@ -40,7 +42,7 @@ namespace llvm { /// Label. unsigned incInstance() { return ++Instance; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 949d907..efaabfb 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -153,8 +153,8 @@ public: /// WriteSegmentLoadCommand - Write a segment load command. /// - /// \arg NumSections - The number of sections in this segment. - /// \arg SectionDataSize - The total size of the sections. + /// \param NumSections The number of sections in this segment. + /// \param SectionDataSize The total size of the sections. void WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, @@ -233,6 +233,8 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); + void markAbsoluteVariableSymbols(MCAssembler &Asm, + const MCAsmLayout &Layout); void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 74e2263..23e5513 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -84,7 +84,8 @@ protected: /// this is the section to emit them into. const MCSection *CompactUnwindSection; - /// DwarfAccelNamesSection, DwarfAccelObjCSection + /// DwarfAccelNamesSection, DwarfAccelObjCSection, + /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - /// If we use the DWARF accelerated hash tables then we want toe emit these /// sections. const MCSection *DwarfAccelNamesSection; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a69075d..08b00f1 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -72,6 +72,13 @@ public: virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace); + virtual void EmitValueToAlignment(unsigned ByteAlignment, + int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0); + virtual void EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit = 0); virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, @@ -80,6 +87,9 @@ public: virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); virtual void EmitGPRel32Value(const MCExpr *Value); + virtual void EmitGPRel64Value(const MCExpr *Value); + virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace); virtual void FinishImpl(); /// @} diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 9591a00..14fe75f 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCOBJECTWRITER_H #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include <cassert> @@ -35,8 +36,8 @@ class MCValue; /// The object writer also contains a number of helper methods for writing /// binary data to the output stream. class MCObjectWriter { - MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT - void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT + MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION; + void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION; protected: raw_ostream &OS; diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 9a8735f..e102dfb 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -31,8 +31,8 @@ class AsmLexer : public MCAsmLexer { const MemoryBuffer *CurBuf; bool isAtStartOfLine; - void operator=(const AsmLexer&); // DO NOT IMPLEMENT - AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT + void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION; + AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION; protected: /// LexToken - Read the next token and return its code. diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 5e29ad4..0a961d6 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCASMLEXER_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/SMLoc.h" @@ -39,6 +40,7 @@ public: // No-value. EndOfStatement, Colon, + Space, Plus, Minus, Tilde, Slash, // '/' BackSlash, // '\' @@ -121,10 +123,11 @@ class MCAsmLexer { SMLoc ErrLoc; std::string Err; - MCAsmLexer(const MCAsmLexer &); // DO NOT IMPLEMENT - void operator=(const MCAsmLexer &); // DO NOT IMPLEMENT + MCAsmLexer(const MCAsmLexer &) LLVM_DELETED_FUNCTION; + void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. const char *TokStart; + bool SkipSpace; MCAsmLexer(); @@ -169,11 +172,14 @@ public: /// getKind - Get the kind of current token. AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - /// is - Check if the current token has kind \arg K. + /// is - Check if the current token has kind \p K. bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - /// isNot - Check if the current token has kind \arg K. + /// isNot - Check if the current token has kind \p K. bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } + + /// setSkipSpace - Set whether spaces should be ignored by the lexer + void setSkipSpace(bool val) { SkipSpace = val; } }; } // End llvm namespace diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 793c709..a71d3c3 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -20,6 +20,9 @@ class MCAsmLexer; class MCAsmParserExtension; class MCContext; class MCExpr; +class MCInstPrinter; +class MCInstrInfo; +class MCParsedAsmOperand; class MCStreamer; class MCTargetAsmParser; class SMLoc; @@ -28,6 +31,16 @@ class SourceMgr; class StringRef; class Twine; +/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. +class MCAsmParserSemaCallback { +public: + virtual ~MCAsmParserSemaCallback(); + virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc, + unsigned &Size) = 0; + virtual bool LookupInlineAsmField(StringRef Base, StringRef Member, + unsigned &Offset) = 0; +}; + /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { @@ -35,8 +48,8 @@ public: typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc); private: - MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT - void operator=(const MCAsmParser &); // DO NOT IMPLEMENT + MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION; + void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION; MCTargetAsmParser *TargetParser; @@ -73,15 +86,26 @@ public: /// Run - Run the parser on the input source buffer. virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; - /// Warning - Emit a warning at the location \arg L, with the message \arg - /// Msg. + virtual void setParsingInlineAsm(bool V) = 0; + virtual bool isParsingInlineAsm() = 0; + + /// ParseMSInlineAsm - Parse ms-style inline assembly. + virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, + unsigned &NumOutputs, unsigned &NumInputs, + SmallVectorImpl<std::pair<void *, bool> > &OpDecls, + SmallVectorImpl<std::string> &Constraints, + SmallVectorImpl<std::string> &Clobbers, + const MCInstrInfo *MII, + const MCInstPrinter *IP, + MCAsmParserSemaCallback &SI) = 0; + + /// Warning - Emit a warning at the location \p L, with the message \p Msg. /// /// \return The return value is true, if warnings are fatal. virtual bool Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0; - /// Error - Emit an error at the location \arg L, with the message \arg - /// Msg. + /// Error - Emit an error at the location \p L, with the message \p Msg. /// /// \return The return value is always true, as an idiomatic convenience to /// clients. @@ -100,7 +124,7 @@ public: ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) - /// and set \arg Res to the identifier contents. + /// and set \p Res to the identifier contents. virtual bool ParseIdentifier(StringRef &Res) = 0; /// \brief Parse up to the end of statement and return the contents from the diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 4e2aee9..0918c93 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -21,8 +21,8 @@ class Twine; /// which is implemented by target and object file assembly parser /// implementations. class MCAsmParserExtension { - MCAsmParserExtension(const MCAsmParserExtension &); // DO NOT IMPLEMENT - void operator=(const MCAsmParserExtension &); // DO NOT IMPLEMENT + MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION; + void operator=(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION; MCAsmParser *Parser; @@ -43,8 +43,8 @@ protected: public: virtual ~MCAsmParserExtension(); - /// \brief Initialize the extension for parsing using the given \arg - /// Parser. The extension should use the AsmParser interfaces to register its + /// \brief Initialize the extension for parsing using the given \p Parser. + /// The extension should use the AsmParser interfaces to register its /// parsing routines. virtual void Initialize(MCAsmParser &Parser); diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 2556e5f..60e7887 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -19,15 +19,69 @@ class raw_ostream; /// base class is used by target-independent clients and is the interface /// between parsing an asm instruction and recognizing it. class MCParsedAsmOperand { + /// MCOperandNum - The corresponding MCInst operand number. Only valid when + /// parsing MS-style inline assembly. + unsigned MCOperandNum; + + /// Constraint - The constraint on this operand. Only valid when parsing + /// MS-style inline assembly. + std::string Constraint; + public: MCParsedAsmOperand() {} virtual ~MCParsedAsmOperand() {} + void setConstraint(StringRef C) { Constraint = C.str(); } + StringRef getConstraint() { return Constraint; } + + void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; } + unsigned getMCOperandNum() { return MCOperandNum; } + + unsigned getNameLen() { + assert (getStartLoc().isValid() && "Invalid StartLoc!"); + assert (getEndLoc().isValid() && "Invalid EndLoc!"); + return getEndLoc().getPointer() - getStartLoc().getPointer(); + } + + StringRef getName() { + return StringRef(getStartLoc().getPointer(), getNameLen()); + } + + /// isToken - Is this a token operand? + virtual bool isToken() const = 0; + /// isImm - Is this an immediate operand? + virtual bool isImm() const = 0; + /// isReg - Is this a register operand? + virtual bool isReg() const = 0; + virtual unsigned getReg() const = 0; + + /// isMem - Is this a memory operand? + virtual bool isMem() const = 0; + virtual unsigned getMemSize() const { return 0; } + /// getStartLoc - Get the location of the first token of this operand. virtual SMLoc getStartLoc() const = 0; /// getEndLoc - Get the location of the last token of this operand. virtual SMLoc getEndLoc() const = 0; + /// needAsmRewrite - AsmRewrites happen in both the target-independent and + /// target-dependent parsers. The target-independent parser calls this + /// function to determine if the target-dependent parser has already taken + /// care of the rewrites. Only valid when parsing MS-style inline assembly. + virtual bool needAsmRewrite() const { return true; } + + /// isOffsetOf - Do we need to emit code to get the offset of the variable, + /// rather then the value of the variable? Only valid when parsing MS-style + /// inline assembly. + virtual bool isOffsetOf() const { return false; } + + /// getOffsetOfLoc - Get the location of the offset operator. + virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } + + /// needSizeDirective - Do we need to emit a sizing directive for this + /// operand? Only valid when parsing MS-style inline assembly. + virtual bool needSizeDirective() const { return false; } + /// print - Print a debug representation of the operand to the given stream. virtual void print(raw_ostream &OS) const = 0; /// dump - Print to the debug stream. diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 46a9d71..f05baea 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -333,6 +333,13 @@ public: return NumRegs; } + /// getNumSubRegIndices - Return the number of sub-register indices + /// understood by the target. Index 0 is reserved for the no-op sub-register, + /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. + unsigned getNumSubRegIndices() const { + return NumSubRegIndices; + } + /// getNumRegUnits - Return the number of (native) register units in the /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They /// can be accessed through MCRegUnitIterator defined below. @@ -363,7 +370,7 @@ public: /// getRegClass - Returns the register class associated with the enumeration /// value. See class MCOperandInfo. - const MCRegisterClass getRegClass(unsigned i) const { + const MCRegisterClass& getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); return Classes[i]; } diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 3b1cdf1..0c71ee5 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -16,17 +16,111 @@ #define LLVM_MC_MCSCHEDMODEL_H #include "llvm/Support/DataTypes.h" +#include <cassert> namespace llvm { struct InstrItinerary; +/// Define a kind of processor resource that will be modeled by the scheduler. +struct MCProcResourceDesc { +#ifndef NDEBUG + const char *Name; +#endif + unsigned NumUnits; // Number of resource of this kind + unsigned SuperIdx; // Index of the resources kind that contains this kind. + + // Buffered resources may be consumed at some indeterminate cycle after + // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered + // resources always consume their resource some fixed number of cycles after + // dispatch (e.g. for instruction interlocking that may stall the pipeline). + bool IsBuffered; + + bool operator==(const MCProcResourceDesc &Other) const { + return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx + && IsBuffered == Other.IsBuffered; + } +}; + +/// Identify one of the processor resource kinds consumed by a particular +/// scheduling class for the specified number of cycles. +struct MCWriteProcResEntry { + unsigned ProcResourceIdx; + unsigned Cycles; + + bool operator==(const MCWriteProcResEntry &Other) const { + return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles; + } +}; + +/// Specify the latency in cpu cycles for a particular scheduling class and def +/// index. -1 indicates an invalid latency. Heuristics would typically consider +/// an instruction with invalid latency to have infinite latency. Also identify +/// the WriteResources of this def. When the operand expands to a sequence of +/// writes, this ID is the last write in the sequence. +struct MCWriteLatencyEntry { + int Cycles; + unsigned WriteResourceID; + + bool operator==(const MCWriteLatencyEntry &Other) const { + return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID; + } +}; + +/// Specify the number of cycles allowed after instruction issue before a +/// particular use operand reads its registers. This effectively reduces the +/// write's latency. Here we allow negative cycles for corner cases where +/// latency increases. This rule only applies when the entry's WriteResource +/// matches the write's WriteResource. +/// +/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by +/// WriteResourceIdx. +struct MCReadAdvanceEntry { + unsigned UseIdx; + unsigned WriteResourceID; + int Cycles; + + bool operator==(const MCReadAdvanceEntry &Other) const { + return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID + && Cycles == Other.Cycles; + } +}; + +/// Summarize the scheduling resources required for an instruction of a +/// particular scheduling class. +/// +/// Defined as an aggregate struct for creating tables with initializer lists. +struct MCSchedClassDesc { + static const unsigned short InvalidNumMicroOps = UINT16_MAX; + static const unsigned short VariantNumMicroOps = UINT16_MAX - 1; + +#ifndef NDEBUG + const char* Name; +#endif + unsigned short NumMicroOps; + bool BeginGroup; + bool EndGroup; + unsigned WriteProcResIdx; // First index into WriteProcResTable. + unsigned NumWriteProcResEntries; + unsigned WriteLatencyIdx; // First index into WriteLatencyTable. + unsigned NumWriteLatencyEntries; + unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable. + unsigned NumReadAdvanceEntries; + + bool isValid() const { + return NumMicroOps != InvalidNumMicroOps; + } + bool isVariant() const { + return NumMicroOps == VariantNumMicroOps; + } +}; + /// Machine model for scheduling, bundling, and heuristics. /// /// The machine model directly provides basic information about the /// microarchitecture to the scheduler in the form of properties. It also -/// optionally refers to scheduler resources tables and itinerary -/// tables. Scheduler resources tables model the latency and cost for each +/// optionally refers to scheduler resource tables and itinerary +/// tables. Scheduler resource tables model the latency and cost for each /// instruction type. Itinerary tables are an independant mechanism that /// provides a detailed reservation table describing each cycle of instruction /// execution. Subtargets may define any or all of the above categories of data @@ -84,8 +178,11 @@ public: static const unsigned DefaultMispredictPenalty = 10; private: - // TODO: Add a reference to proc resource types and sched resource tables. - + unsigned ProcID; + const MCProcResourceDesc *ProcResourceTable; + const MCSchedClassDesc *SchedClassTable; + unsigned NumProcResourceKinds; + unsigned NumSchedClasses; // Instruction itinerary tables used by InstrItineraryData. friend class InstrItineraryData; const InstrItinerary *InstrItineraries; @@ -100,13 +197,45 @@ public: LoadLatency(DefaultLoadLatency), HighLatency(DefaultHighLatency), MispredictPenalty(DefaultMispredictPenalty), - InstrItineraries(0) {} + ProcID(0), ProcResourceTable(0), SchedClassTable(0), + NumProcResourceKinds(0), NumSchedClasses(0), + InstrItineraries(0) { + (void)NumProcResourceKinds; + (void)NumSchedClasses; + } // Table-gen driven ctor. MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, + unsigned pi, const MCProcResourceDesc *pr, + const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, const InstrItinerary *ii): IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), - MispredictPenalty(mp), InstrItineraries(ii){} + MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), + SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), + InstrItineraries(ii) {} + + unsigned getProcessorID() const { return ProcID; } + + /// Does this machine model include instruction-level scheduling. + bool hasInstrSchedModel() const { return SchedClassTable; } + + unsigned getNumProcResourceKinds() const { + return NumProcResourceKinds; + } + + const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx"); + return &ProcResourceTable[ProcResourceIdx]; + } + + const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx"); + return &SchedClassTable[SchedClassIdx]; + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 7da6534..21fdb6b 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -15,7 +15,7 @@ #define LLVM_MC_MCSECTION_H #include "llvm/MC/SectionKind.h" -#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" namespace llvm { class MCAsmInfo; @@ -33,8 +33,8 @@ namespace llvm { }; private: - MCSection(const MCSection&); // DO NOT IMPLEMENT - void operator=(const MCSection&); // DO NOT IMPLEMENT + MCSection(const MCSection&) LLVM_DELETED_FUNCTION; + void operator=(const MCSection&) LLVM_DELETED_FUNCTION; protected: MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {} SectionVariant Variant; @@ -64,8 +64,6 @@ namespace llvm { /// isVirtualSection - Check whether this section is "virtual", that is /// has no actual object file contents. virtual bool isVirtualSection() const = 0; - - static bool classof(const MCSection *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 7eacde5..b050c0f 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -61,7 +61,6 @@ namespace llvm { static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } - static bool classof(const MCSectionCOFF *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 7321ca8..4d54465 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -76,7 +76,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } - static bool classof(const MCSectionELF *) { return true; } // Return the entry size for sections with fixed-width data. static unsigned DetermineEntrySize(SectionKind Kind); diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 15eb4f4..71ea8f3 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -174,7 +174,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; } - static bool classof(const MCSectionMachO *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index e8c3e59..230d27e 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -47,8 +47,8 @@ namespace llvm { class MCStreamer { MCContext &Context; - MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT - MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT + MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; + MCStreamer &operator=(const MCStreamer&) LLVM_DELETED_FUNCTION; bool EmitEHFrame; bool EmitDebugFrame; @@ -342,7 +342,7 @@ namespace llvm { /// @name Generating Data /// @{ - /// EmitBytes - Emit the bytes in \arg Data into the output. + /// EmitBytes - Emit the bytes in \p Data into the output. /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. @@ -554,6 +554,11 @@ namespace llvm { virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); + /// PPC-related methods. + /// FIXME: Eventually replace it with some "target MC streamer" and move + /// these methods there. + virtual void EmitTCEntry(const MCSymbol &S); + /// FinishImpl - Streamer specific finalization. virtual void FinishImpl() = 0; /// Finish - Finish emission of machine code. @@ -573,17 +578,14 @@ namespace llvm { /// InstPrint. /// /// \param CE - If given, a code emitter to use to show the instruction - /// encoding inline with the assembly. This method takes ownership of \arg CE. + /// encoding inline with the assembly. This method takes ownership of \p CE. /// /// \param TAB - If given, a target asm backend to use to show the fixup /// information in conjunction with encoding information. This method takes - /// ownership of \arg TAB. + /// ownership of \p TAB. /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. - /// - /// \param DecodeLSDA - If true, emit comments that translates the LSDA into a - /// human readable format. Only usable with CFI. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, @@ -597,7 +599,7 @@ namespace llvm { /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); @@ -605,7 +607,7 @@ namespace llvm { /// createWinCOFFStreamer - Create a machine code streamer which will /// generate Microsoft COFF format object files. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB, MCCodeEmitter &CE, raw_ostream &OS, @@ -620,7 +622,7 @@ namespace llvm { /// createPureStreamer - Create a machine code streamer which will generate /// "pure" MC object files, for use with MC-JIT and testing tools. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE); diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 31d632d..69213cd 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -30,7 +30,14 @@ class MCSubtargetInfo { std::string TargetTriple; // Target triple const SubtargetFeatureKV *ProcFeatures; // Processor feature list const SubtargetFeatureKV *ProcDesc; // Processor descriptions - const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model + + // Scheduler machine model + const SubtargetInfoKV *ProcSchedModels; + const MCWriteProcResEntry *WriteProcResTable; + const MCWriteLatencyEntry *WriteLatencyTable; + const MCReadAdvanceEntry *ReadAdvanceTable; + const MCSchedModel *CPUSchedModel; + const InstrStage *Stages; // Instruction itinerary stages const unsigned *OperandCycles; // Itinerary operand cycles const unsigned *ForwardingPaths; // Forwarding paths @@ -43,6 +50,9 @@ public: const SubtargetFeatureKV *PF, const SubtargetFeatureKV *PD, const SubtargetInfoKV *ProcSched, + const MCWriteProcResEntry *WPR, + const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC, const unsigned *FP, unsigned NF, unsigned NP); @@ -58,9 +68,9 @@ public: return FeatureBits; } - /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with - /// feature string), recompute and return feature bits. - uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS); + /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with + /// feature string). Recompute feature bits and scheduling model. + void InitMCProcessorInfo(StringRef CPU, StringRef FS); /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version does not change the implied bits. @@ -72,11 +82,56 @@ public: /// getSchedModelForCPU - Get the machine model of a CPU. /// - MCSchedModel *getSchedModelForCPU(StringRef CPU) const; + const MCSchedModel *getSchedModelForCPU(StringRef CPU) const; + + /// getSchedModel - Get the machine model for this subtarget's CPU. + /// + const MCSchedModel *getSchedModel() const { return CPUSchedModel; } + + /// Return an iterator at the first process resource consumed by the given + /// scheduling class. + const MCWriteProcResEntry *getWriteProcResBegin( + const MCSchedClassDesc *SC) const { + return &WriteProcResTable[SC->WriteProcResIdx]; + } + const MCWriteProcResEntry *getWriteProcResEnd( + const MCSchedClassDesc *SC) const { + return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries; + } + + const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC, + unsigned DefIdx) const { + assert(DefIdx < SC->NumWriteLatencyEntries && + "MachineModel does not specify a WriteResource for DefIdx"); + + return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx]; + } + + int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, + unsigned WriteResID) const { + // TODO: The number of read advance entries in a class can be significant + // (~50). Consider compressing the WriteID into a dense ID of those that are + // used by ReadAdvance and representing them as a bitset. + for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx], + *E = I + SC->NumReadAdvanceEntries; I != E; ++I) { + if (I->UseIdx < UseIdx) + continue; + if (I->UseIdx > UseIdx) + break; + // Find the first WriteResIdx match, which has the highest cycle count. + if (!I->WriteResourceID || I->WriteResourceID == WriteResID) { + return I->Cycles; + } + } + return 0; + } /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. /// InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; + + /// Initialize an InstrItineraryData instance. + void initInstrItins(InstrItineraryData &InstrItins) const; }; } // End llvm namespace diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 0583ce5..fe92755 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSYMBOL_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" namespace llvm { class MCExpr; @@ -62,8 +63,8 @@ namespace llvm { : Name(name), Section(0), Value(0), IsTemporary(isTemporary), IsUsed(false) {} - MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT - void operator=(const MCSymbol&); // DO NOT IMPLEMENT + MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION; + void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION; public: /// getName - Get the symbol name. StringRef getName() const { return Name; } @@ -112,7 +113,7 @@ namespace llvm { return *Section; } - /// setSection - Mark the symbol as defined in the section \arg S. + /// setSection - Mark the symbol as defined in the section \p S. void setSection(const MCSection &S) { Section = &S; } /// setUndefined - Mark the symbol as undefined. @@ -132,7 +133,7 @@ namespace llvm { return Value != 0; } - /// getValue() - Get the value for variable symbols. + /// getVariableValue() - Get the value for variable symbols. const MCExpr *getVariableValue() const { assert(isVariable() && "Invalid accessor!"); IsUsed = true; @@ -148,7 +149,7 @@ namespace llvm { /// @} - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h index f5c8c09..b1cc546 100644 --- a/include/llvm/MC/MCTargetAsmLexer.h +++ b/include/llvm/MC/MCTargetAsmLexer.h @@ -24,8 +24,8 @@ class MCTargetAsmLexer { SMLoc ErrLoc; std::string Err; - MCTargetAsmLexer(const MCTargetAsmLexer &); // DO NOT IMPLEMENT - void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT + MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; + void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. MCTargetAsmLexer(const Target &); @@ -45,7 +45,7 @@ public: const Target &getTarget() const { return TheTarget; } - /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L. + /// InstallLexer - Set the lexer to get tokens from lower-level lexer \p L. void InstallLexer(MCAsmLexer &L) { Lexer = &L; } @@ -77,10 +77,10 @@ public: /// getKind - Get the kind of current token. AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - /// is - Check if the current token has kind \arg K. + /// is - Check if the current token has kind \p K. bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - /// isNot - Check if the current token has kind \arg K. + /// isNot - Check if the current token has kind \p K. bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } }; diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 929a204..483a80b 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -21,11 +21,43 @@ class MCParsedAsmOperand; class MCInst; template <typename T> class SmallVectorImpl; +enum AsmRewriteKind { + AOK_DotOperator, // Rewrite a dot operator expression as an immediate. + // E.g., [eax].foo.bar -> [eax].8 + AOK_Emit, // Rewrite _emit as .byte. + AOK_Imm, // Rewrite as $$N. + AOK_ImmPrefix, // Add $$ before a parsed Imm. + AOK_Input, // Rewrite in terms of $N. + AOK_Output, // Rewrite in terms of $N. + AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). + AOK_Skip // Skip emission (e.g., offset/type operators). +}; + +struct AsmRewrite { + AsmRewriteKind Kind; + SMLoc Loc; + unsigned Len; + unsigned Val; +public: + AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0) + : Kind(kind), Loc(loc), Len(len), Val(val) {} +}; + +struct ParseInstructionInfo { + + SmallVectorImpl<AsmRewrite> *AsmRewrites; + + ParseInstructionInfo() : AsmRewrites(0) {} + ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites) + : AsmRewrites(rewrites) {} + + ~ParseInstructionInfo() {} +}; + /// MCTargetAsmParser - Generic interface to target specific assembly parsers. class MCTargetAsmParser : public MCAsmParserExtension { public: enum MatchResultTy { - Match_ConversionFail, Match_InvalidOperand, Match_MissingFeature, Match_MnemonicFail, @@ -34,20 +66,34 @@ public: }; private: - MCTargetAsmParser(const MCTargetAsmParser &); // DO NOT IMPLEMENT - void operator=(const MCTargetAsmParser &); // DO NOT IMPLEMENT + MCTargetAsmParser(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION; + void operator=(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. MCTargetAsmParser(); /// AvailableFeatures - The current set of available features. unsigned AvailableFeatures; + /// ParsingInlineAsm - Are we parsing ms-style inline assembly? + bool ParsingInlineAsm; + + /// SemaCallback - The Sema callback implementation. Must be set when parsing + /// ms-style inline assembly. + MCAsmParserSemaCallback *SemaCallback; + public: virtual ~MCTargetAsmParser(); unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } + bool isParsingInlineAsm () { return ParsingInlineAsm; } + void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; } + + void setSemaCallback(MCAsmParserSemaCallback *Callback) { + SemaCallback = Callback; + } + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; @@ -64,7 +110,8 @@ public: /// \param Operands [out] - The list of parsed operands, this returns /// ownership of them to the caller. /// \return True on failure. - virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, + virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, + SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; /// ParseDirective - Parse a target specific assembler directive @@ -79,18 +126,9 @@ public: /// \param DirectiveID - the identifier token of the directive. virtual bool ParseDirective(AsmToken DirectiveID) = 0; - /// MatchInstruction - Recognize a series of operands of a parsed instruction - /// as an actual MCInst. This returns false on success and returns true on - /// failure to match. - /// - /// On failure, the target parser is responsible for emitting a diagnostic - /// explaining the match failure. - virtual bool - MatchInstruction(SMLoc IDLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - SmallVectorImpl<MCInst> &MCInsts) { - return true; - } + /// mnemonicIsValid - This returns true if this is a valid mnemonic and false + /// otherwise. + virtual bool mnemonicIsValid(StringRef Mnemonic) = 0; /// MatchAndEmitInstruction - Recognize a series of operands of a parsed /// instruction as an actual MCInst and emit it to the specified MCStreamer. @@ -99,9 +137,10 @@ public: /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. virtual bool - MatchAndEmitInstruction(SMLoc IDLoc, + MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out) = 0; + MCStreamer &Out, unsigned &ErrorInfo, + bool MatchingInlineAsm) = 0; /// checkTargetMatchPredicate - Validate the instruction match against /// any complex target predicates not expressible via match classes. @@ -109,6 +148,8 @@ public: return Match_Success; } + virtual void convertToMapAndConstraints(unsigned Kind, + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; }; } // End llvm namespace diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 8352ed1..f9af8bc 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -46,7 +46,7 @@ public: /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 507d882..57f0518 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -50,7 +50,7 @@ struct SubtargetFeatureKV { // struct SubtargetInfoKV { const char *Key; // K-V key string - void *Value; // K-V pointer value + const void *Value; // K-V pointer value // Compare routine for std binary search bool operator<(const SubtargetInfoKV &S) const { @@ -95,10 +95,6 @@ public: const SubtargetFeatureKV *FeatureTable, size_t FeatureTableSize); - /// Get scheduling itinerary of a CPU. - void *getItinerary(const StringRef CPU, - const SubtargetInfoKV *Table, size_t TableSize); - /// Print feature string. void print(raw_ostream &OS) const; diff --git a/include/llvm/MDBuilder.h b/include/llvm/MDBuilder.h index 2aa48b0..1867a63 100644 --- a/include/llvm/MDBuilder.h +++ b/include/llvm/MDBuilder.h @@ -134,6 +134,27 @@ namespace llvm { } } + struct TBAAStructField { + uint64_t Offset; + uint64_t Size; + MDNode *TBAA; + TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : + Offset(Offset), Size(Size), TBAA(TBAA) {} + }; + + /// \brief Return metadata for a tbaa.struct node with the given + /// struct field descriptions. + MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { + SmallVector<Value *, 4> Vals(Fields.size() * 3); + Type *Int64 = IntegerType::get(Context, 64); + for (unsigned i = 0, e = Fields.size(); i != e; ++i) { + Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); + Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); + Vals[i * 3 + 2] = Fields[i].TBAA; + } + return MDNode::get(Context, Vals); + } + }; } // end namespace llvm diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index b40549b..0fbbb95 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -37,7 +37,7 @@ template<typename ValueSubClass, typename ItemParentClass> /// MDString is always unnamed. class MDString : public Value { virtual void anchor(); - MDString(const MDString &); // DO NOT IMPLEMENT + MDString(const MDString &) LLVM_DELETED_FUNCTION; explicit MDString(LLVMContext &C); public: @@ -59,7 +59,6 @@ public: iterator end() const { return getName().end(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MDString *) { return true; } static bool classof(const Value *V) { return V->getValueID() == MDStringVal; } @@ -71,8 +70,8 @@ class MDNodeOperand; //===----------------------------------------------------------------------===// /// MDNode - a tuple of other values. class MDNode : public Value, public FoldingSetNode { - MDNode(const MDNode &); // DO NOT IMPLEMENT - void operator=(const MDNode &); // DO NOT IMPLEMENT + MDNode(const MDNode &) LLVM_DELETED_FUNCTION; + void operator=(const MDNode &) LLVM_DELETED_FUNCTION; friend class MDNodeOperand; friend class LLVMContextImpl; friend struct FoldingSetTrait<MDNode>; @@ -161,7 +160,6 @@ public: void Profile(FoldingSetNodeID &ID) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MDNode *) { return true; } static bool classof(const Value *V) { return V->getValueID() == MDNodeVal; } @@ -195,7 +193,7 @@ class NamedMDNode : public ilist_node<NamedMDNode> { friend struct ilist_traits<NamedMDNode>; friend class LLVMContextImpl; friend class Module; - NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT + NamedMDNode(const NamedMDNode &) LLVM_DELETED_FUNCTION; std::string Name; Module *Parent; diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 358b27a..f3d8249 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -129,7 +129,6 @@ public: symbol_iterator end_symbols() const; // Cast methods. - static inline bool classof(Archive const *v) { return true; } static inline bool classof(Binary const *v) { return v->isArchive(); } diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index befe812..d555de3 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -26,8 +26,8 @@ namespace object { class Binary { private: - Binary(); // = delete - Binary(const Binary &other); // = delete + Binary() LLVM_DELETED_FUNCTION; + Binary(const Binary &other) LLVM_DELETED_FUNCTION; unsigned int TypeID; @@ -64,7 +64,6 @@ public: // Cast methods. unsigned int getType() const { return TypeID; } - static inline bool classof(const Binary *v) { return true; } // Convenience methods bool isObject() const { diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 967420e..6f42d76 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -116,6 +116,7 @@ protected: virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const; + virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; @@ -128,6 +129,7 @@ protected: virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, @@ -197,7 +199,6 @@ public: static inline bool classof(const Binary *v) { return v->isCOFF(); } - static inline bool classof(const COFFObjectFile *v) { return true; } }; } diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 7698441..466de93 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -387,11 +387,65 @@ struct Elf_Rel_Impl<target_endianness, false, isRela> } }; +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Ehdr_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes + Elf_Half e_type; // Type of file (see ET_*) + Elf_Half e_machine; // Required architecture for this file (see EM_*) + Elf_Word e_version; // Must be equal to 1 + Elf_Addr e_entry; // Address to jump to in order to start program + Elf_Off e_phoff; // Program header table's file offset, in bytes + Elf_Off e_shoff; // Section header table's file offset, in bytes + Elf_Word e_flags; // Processor-specific flags + Elf_Half e_ehsize; // Size of ELF header, in bytes + Elf_Half e_phentsize;// Size of an entry in the program header table + Elf_Half e_phnum; // Number of entries in the program header table + Elf_Half e_shentsize;// Size of an entry in the section header table + Elf_Half e_shnum; // Number of entries in the section header table + Elf_Half e_shstrndx; // Section header table index of section name + // string table + bool checkMagic() const { + return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; + } + unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } + unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } +}; + +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Phdr; + +template<support::endianness target_endianness> +struct Elf_Phdr<target_endianness, false> { + LLVM_ELF_IMPORT_TYPES(target_endianness, false) + Elf_Word p_type; // Type of segment + Elf_Off p_offset; // FileOffset where segment is located, in bytes + Elf_Addr p_vaddr; // Virtual Address of beginning of segment + Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) + Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) + Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) + Elf_Word p_flags; // Segment flags + Elf_Word p_align; // Segment alignment constraint +}; + +template<support::endianness target_endianness> +struct Elf_Phdr<target_endianness, true> { + LLVM_ELF_IMPORT_TYPES(target_endianness, true) + Elf_Word p_type; // Type of segment + Elf_Word p_flags; // Segment flags + Elf_Off p_offset; // FileOffset where segment is located, in bytes + Elf_Addr p_vaddr; // Virtual Address of beginning of segment + Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) + Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) + Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) + Elf_Word p_align; // Segment alignment constraint +}; template<support::endianness target_endianness, bool is64Bits> class ELFObjectFile : public ObjectFile { LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr; typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; @@ -406,28 +460,6 @@ class ELFObjectFile : public ObjectFile { typedef content_iterator<DynRef> dyn_iterator; protected: - struct Elf_Ehdr { - unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes - Elf_Half e_type; // Type of file (see ET_*) - Elf_Half e_machine; // Required architecture for this file (see EM_*) - Elf_Word e_version; // Must be equal to 1 - Elf_Addr e_entry; // Address to jump to in order to start program - Elf_Off e_phoff; // Program header table's file offset, in bytes - Elf_Off e_shoff; // Section header table's file offset, in bytes - Elf_Word e_flags; // Processor-specific flags - Elf_Half e_ehsize; // Size of ELF header, in bytes - Elf_Half e_phentsize;// Size of an entry in the program header table - Elf_Half e_phnum; // Number of entries in the program header table - Elf_Half e_shentsize;// Size of an entry in the section header table - Elf_Half e_shnum; // Number of entries in the section header table - Elf_Half e_shstrndx; // Section header table index of section name - // string table - bool checkMagic() const { - return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; - } - unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } - unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } - }; // This flag is used for classof, to distinguish ELFObjectFile from // its subclass. If more subclasses will be created, this flag will // have to become an enum. @@ -459,6 +491,59 @@ private: // This is set the first time getLoadName is called. mutable const char *dt_soname; +public: + /// \brief Iterate over relocations in a .rel or .rela section. + template<class RelocT> + class ELFRelocationIterator { + public: + typedef void difference_type; + typedef const RelocT value_type; + typedef std::forward_iterator_tag iterator_category; + typedef value_type &reference; + typedef value_type *pointer; + + /// \brief Default construct iterator. + ELFRelocationIterator() : Section(0), Current(0) {} + ELFRelocationIterator(const Elf_Shdr *Sec, const char *Start) + : Section(Sec) + , Current(Start) {} + + reference operator *() { + assert(Current && "Attempted to dereference an invalid iterator!"); + return *reinterpret_cast<const RelocT*>(Current); + } + + pointer operator ->() { + assert(Current && "Attempted to dereference an invalid iterator!"); + return reinterpret_cast<const RelocT*>(Current); + } + + bool operator ==(const ELFRelocationIterator &Other) { + return Section == Other.Section && Current == Other.Current; + } + + bool operator !=(const ELFRelocationIterator &Other) { + return !(*this == Other); + } + + ELFRelocationIterator &operator ++(int) { + assert(Current && "Attempted to increment an invalid iterator!"); + Current += Section->sh_entsize; + return *this; + } + + ELFRelocationIterator operator ++() { + ELFRelocationIterator Tmp = *this; + ++*this; + return Tmp; + } + + private: + const Elf_Shdr *Section; + const char *Current; + }; + +private: // Records for each version index the corresponding Verdef or Vernaux entry. // This is filled the first time LoadVersionMap() is called. class VersionMapEntry : public PointerIntPair<const void*, 1> { @@ -535,6 +620,7 @@ protected: virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const; + virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; friend class DynRefImpl<target_endianness, is64Bits>; virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const; @@ -555,6 +641,7 @@ protected: bool &Res) const; virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; @@ -594,6 +681,27 @@ public: virtual dyn_iterator begin_dynamic_table() const; virtual dyn_iterator end_dynamic_table() const; + typedef ELFRelocationIterator<Elf_Rela> Elf_Rela_Iter; + typedef ELFRelocationIterator<Elf_Rel> Elf_Rel_Iter; + + virtual Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { + return Elf_Rela_Iter(sec, (const char *)(base() + sec->sh_offset)); + } + + virtual Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { + return Elf_Rela_Iter(sec, (const char *) + (base() + sec->sh_offset + sec->sh_size)); + } + + virtual Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { + return Elf_Rel_Iter(sec, (const char *)(base() + sec->sh_offset)); + } + + virtual Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { + return Elf_Rel_Iter(sec, (const char *) + (base() + sec->sh_offset + sec->sh_size)); + } + virtual uint8_t getBytesInAddress() const; virtual StringRef getFileFormatName() const; virtual StringRef getObjectType() const { return "ELF"; } @@ -608,6 +716,7 @@ public: const Elf_Shdr *getSection(const Elf_Sym *symb) const; const Elf_Shdr *getElfSection(section_iterator &It) const; const Elf_Sym *getElfSymbol(symbol_iterator &It) const; + const Elf_Sym *getElfSymbol(uint32_t index) const; // Methods for type inquiry through isa, cast, and dyn_cast bool isDyldType() const { return isDyldELFObject; } @@ -615,7 +724,6 @@ public: return v->getType() == getELFType(target_endianness == support::little, is64Bits); } - static inline bool classof(const ELFObjectFile *v) { return true; } }; // Iterate through the version definitions, and place each Elf_Verdef @@ -804,6 +912,16 @@ ELFObjectFile<target_endianness, is64Bits> } template<support::endianness target_endianness, bool is64Bits> +const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * +ELFObjectFile<target_endianness, is64Bits> + ::getElfSymbol(uint32_t index) const { + DataRefImpl SymbolData; + SymbolData.d.a = index; + SymbolData.d.b = 1; + return getSymbol(SymbolData); +} + +template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> ::getSymbolFileOffset(DataRefImpl Symb, uint64_t &Result) const { @@ -863,7 +981,18 @@ error_code ELFObjectFile<target_endianness, is64Bits> case ELF::STT_FUNC: case ELF::STT_OBJECT: case ELF::STT_NOTYPE: - Result = symb->st_value + (Section ? Section->sh_addr : 0); + bool IsRelocatable; + switch(Header->e_type) { + case ELF::ET_EXEC: + case ELF::ET_DYN: + IsRelocatable = false; + break; + default: + IsRelocatable = true; + } + Result = symb->st_value; + if (IsRelocatable && Section != 0) + Result += Section->sh_addr; return object_error::success; default: Result = UnknownAddressOrSize; @@ -1034,6 +1163,16 @@ error_code ELFObjectFile<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> + ::getSymbolValue(DataRefImpl Symb, + uint64_t &Val) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + Val = symb->st_value; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const { const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); sec += Header->e_shentsize; @@ -1160,7 +1299,8 @@ error_code ELFObjectFile<target_endianness, is64Bits> } template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits>::isSectionZeroInit(DataRefImpl Sec, +error_code ELFObjectFile<target_endianness, is64Bits> + ::isSectionZeroInit(DataRefImpl Sec, bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); // For ELF, all zero-init sections are virtual (that is, they occupy no space @@ -1174,6 +1314,18 @@ error_code ELFObjectFile<target_endianness, is64Bits>::isSectionZeroInit(DataRef template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> + ::isSectionReadOnlyData(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); + if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR) + Result = false; + else + Result = true; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> ::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const { @@ -1444,6 +1596,143 @@ error_code ELFObjectFile<target_endianness, is64Bits> res = "Unknown"; } break; + case ELF::EM_ARM: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ABS5); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BREL_ADJ); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_SWI8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_XPC25); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_XPC22); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPMOD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_TPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_COPY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GLOB_DAT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP_SLOT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_RELATIVE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_PREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_ABS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_7_0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_15_8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_23_15); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SBREL_11_0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_19_12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_27_20_CK); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL31); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_V4BX); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PREL31); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_ABS_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_ABS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_PREL_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_PREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_ABS_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_ABS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_PREL_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_PREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP19); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP6); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ALU_PREL_11_0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32_NOI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32_NOI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_BREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_BREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GOTDESC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESCSEQ); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32_ABS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_ABS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_PREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTRELAX); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTENTRY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTINHERIT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP11); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDM32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE12GP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_3); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_4); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_5); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_6); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_7); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_9); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_10); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_11); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_13); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_14); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_15); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32); + default: + res = "Unknown"; + } + break; case ELF::EM_HEXAGON: switch (type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE); @@ -1574,15 +1863,15 @@ error_code ELFObjectFile<target_endianness, is64Bits> int64_t addend = 0; uint16_t symbol_index = 0; switch (sec->sh_type) { - default : + default: return object_error::parse_failed; - case ELF::SHT_REL : { + case ELF::SHT_REL: { type = getRel(Rel)->getType(); symbol_index = getRel(Rel)->getSymbol(); // TODO: Read implicit addend from section data. break; } - case ELF::SHT_RELA : { + case ELF::SHT_RELA: { type = getRela(Rel)->getType(); symbol_index = getRela(Rel)->getSymbol(); addend = getRela(Rel)->r_addend; @@ -1596,9 +1885,8 @@ error_code ELFObjectFile<target_endianness, is64Bits> switch (Header->e_machine) { case ELF::EM_X86_64: switch (type) { - case ELF::R_X86_64_32S: - res = symname; - break; + case ELF::R_X86_64_PC8: + case ELF::R_X86_64_PC16: case ELF::R_X86_64_PC32: { std::string fmtbuf; raw_string_ostream fmt(fmtbuf); @@ -1607,10 +1895,23 @@ error_code ELFObjectFile<target_endianness, is64Bits> Result.append(fmtbuf.begin(), fmtbuf.end()); } break; + case ELF::R_X86_64_8: + case ELF::R_X86_64_16: + case ELF::R_X86_64_32: + case ELF::R_X86_64_32S: + case ELF::R_X86_64_64: { + std::string fmtbuf; + raw_string_ostream fmt(fmtbuf); + fmt << symname << (addend < 0 ? "" : "+") << addend; + fmt.flush(); + Result.append(fmtbuf.begin(), fmtbuf.end()); + } + break; default: res = "Unknown"; } break; + case ELF::EM_ARM: case ELF::EM_HEXAGON: res = symname; break; @@ -2024,6 +2325,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits> return "ELF64-i386"; case ELF::EM_X86_64: return "ELF64-x86-64"; + case ELF::EM_PPC64: + return "ELF64-ppc64"; default: return "ELF64-unknown"; } @@ -2044,6 +2347,11 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { return Triple::arm; case ELF::EM_HEXAGON: return Triple::hexagon; + case ELF::EM_MIPS: + return (target_endianness == support::little) ? + Triple::mipsel : Triple::mips; + case ELF::EM_PPC64: + return Triple::ppc64; default: return Triple::UnknownArch; } diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 0b73f94..4e03daa 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -49,7 +49,6 @@ public: static inline bool classof(const Binary *v) { return v->isMachO(); } - static inline bool classof(const MachOObjectFile *v) { return true; } protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; @@ -62,6 +61,7 @@ protected: virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const; + virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; @@ -76,6 +76,7 @@ protected: bool &Res) const; virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h index f30d431..c0f700d 100644 --- a/include/llvm/Object/MachOFormat.h +++ b/include/llvm/Object/MachOFormat.h @@ -61,7 +61,10 @@ namespace mach { CSARM_V6 = 6, CSARM_V5TEJ = 7, CSARM_XSCALE = 8, - CSARM_V7 = 9 + CSARM_V7 = 9, + CSARM_V7F = 10, + CSARM_V7S = 11, + CSARM_V7K = 12 }; /// \brief PowerPC Machine Subtypes. @@ -273,6 +276,10 @@ namespace macho { uint16_t Flags; uint32_t Value; }; + // Despite containing a uint64_t, this structure is only 4-byte aligned within + // a MachO file. +#pragma pack(push) +#pragma pack(4) struct Symbol64TableEntry { uint32_t StringIndex; uint8_t Type; @@ -280,6 +287,7 @@ namespace macho { uint16_t Flags; uint64_t Value; }; +#pragma pack(pop) /// @} /// @name Data-in-code Table Entry diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 2ec656b..1a3120a 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -76,13 +76,13 @@ public: } }; -inline bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { +inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } -inline bool operator <(const DataRefImpl &a, const DataRefImpl &b) { +inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; @@ -144,7 +144,7 @@ public: SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; - bool operator <(const SectionRef &Other) const; + bool operator<(const SectionRef &Other) const; error_code getNext(SectionRef &Result) const; @@ -163,6 +163,7 @@ public: error_code isRequiredForExecution(bool &Result) const; error_code isVirtual(bool &Result) const; error_code isZeroInit(bool &Result) const; + error_code isReadOnlyData(bool &Result) const; error_code containsSymbol(SymbolRef S, bool &Result) const; @@ -207,11 +208,13 @@ public: SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); bool operator==(const SymbolRef &Other) const; - bool operator <(const SymbolRef &Other) const; + bool operator<(const SymbolRef &Other) const; error_code getNext(SymbolRef &Result) const; error_code getName(StringRef &Result) const; + /// Returns the symbol virtual address (i.e. address at which it will be + /// mapped). error_code getAddress(uint64_t &Result) const; error_code getFileOffset(uint64_t &Result) const; error_code getSize(uint64_t &Result) const; @@ -231,6 +234,9 @@ public: /// end_sections() if it is undefined or is an absolute symbol. error_code getSection(section_iterator &Result) const; + /// @brief Get value of the symbol in the symbol table. + error_code getValue(uint64_t &Val) const; + DataRefImpl getRawDataRefImpl() const; }; typedef content_iterator<SymbolRef> symbol_iterator; @@ -248,7 +254,7 @@ public: LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner); bool operator==(const LibraryRef &Other) const; - bool operator <(const LibraryRef &Other) const; + bool operator<(const LibraryRef &Other) const; error_code getNext(LibraryRef &Result) const; @@ -263,11 +269,11 @@ const uint64_t UnknownAddressOrSize = ~0ULL; /// ObjectFile - This class is the base class for all object file types. /// Concrete instances of this object are created by createObjectFile, which -/// figure out which type to create. +/// figures out which type to create. class ObjectFile : public Binary { virtual void anchor(); - ObjectFile(); // = delete - ObjectFile(const ObjectFile &other); // = delete + ObjectFile() LLVM_DELETED_FUNCTION; + ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; protected: ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec); @@ -287,8 +293,8 @@ protected: friend class SymbolRef; virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; - virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0; - virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const =0; + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; + virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; @@ -297,6 +303,7 @@ protected: uint32_t &Res) const = 0; virtual error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const = 0; + virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0; // Same as above for SectionRef. friend class SectionRef; @@ -314,6 +321,7 @@ protected: // A section is 'virtual' if its contents aren't present in the object image. virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const = 0; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; @@ -384,7 +392,6 @@ public: static inline bool classof(const Binary *v) { return v->isObject(); } - static inline bool classof(const ObjectFile *v) { return true; } public: static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); @@ -401,7 +408,7 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const { return SymbolPimpl == Other.SymbolPimpl; } -inline bool SymbolRef::operator <(const SymbolRef &Other) const { +inline bool SymbolRef::operator<(const SymbolRef &Other) const { return SymbolPimpl < Other.SymbolPimpl; } @@ -441,6 +448,10 @@ inline error_code SymbolRef::getType(SymbolRef::Type &Result) const { return OwningObject->getSymbolType(SymbolPimpl, Result); } +inline error_code SymbolRef::getValue(uint64_t &Val) const { + return OwningObject->getSymbolValue(SymbolPimpl, Val); +} + inline DataRefImpl SymbolRef::getRawDataRefImpl() const { return SymbolPimpl; } @@ -456,7 +467,7 @@ inline bool SectionRef::operator==(const SectionRef &Other) const { return SectionPimpl == Other.SectionPimpl; } -inline bool SectionRef::operator <(const SectionRef &Other) const { +inline bool SectionRef::operator<(const SectionRef &Other) const { return SectionPimpl < Other.SectionPimpl; } @@ -508,6 +519,10 @@ inline error_code SectionRef::isZeroInit(bool &Result) const { return OwningObject->isSectionZeroInit(SectionPimpl, Result); } +inline error_code SectionRef::isReadOnlyData(bool &Result) const { + return OwningObject->isSectionReadOnlyData(SectionPimpl, Result); +} + inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, Result); @@ -586,7 +601,7 @@ inline bool LibraryRef::operator==(const LibraryRef &Other) const { return LibraryPimpl == Other.LibraryPimpl; } -inline bool LibraryRef::operator <(const LibraryRef &Other) const { +inline bool LibraryRef::operator<(const LibraryRef &Other) const { return LibraryPimpl < Other.LibraryPimpl; } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h new file mode 100644 index 0000000..7668bde --- /dev/null +++ b/include/llvm/Object/RelocVisitor.h @@ -0,0 +1,131 @@ +//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a wrapper around all the different types of relocations +// in different file formats, such that a client can handle them in a unified +// manner by only implementing a minimal number of functions. +// +//===----------------------------------------------------------------------===// + +#ifndef _LLVM_OBJECT_RELOCVISITOR +#define _LLVM_OBJECT_RELOCVISITOR + +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/ELF.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { +namespace object { + +struct RelocToApply { + // The computed value after applying the relevant relocations. + int64_t Value; + + // The width of the value; how many bytes to touch when applying the + // relocation. + char Width; + RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {} + RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} + RelocToApply() : Value(0), Width(0) {} +}; + +/// @brief Base class for object file relocation visitors. +class RelocVisitor { +public: + explicit RelocVisitor(llvm::StringRef FileFormat) + : FileFormat(FileFormat), HasError(false) {} + + // TODO: Should handle multiple applied relocations via either passing in the + // previously computed value or just count paired relocations as a single + // visit. + RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0, + uint64_t Value = 0) { + if (FileFormat == "ELF64-x86-64") { + switch (RelocType) { + case llvm::ELF::R_X86_64_NONE: + return visitELF_X86_64_NONE(R); + case llvm::ELF::R_X86_64_64: + return visitELF_X86_64_64(R, Value); + case llvm::ELF::R_X86_64_PC32: + return visitELF_X86_64_PC32(R, Value, SecAddr); + case llvm::ELF::R_X86_64_32: + return visitELF_X86_64_32(R, Value); + case llvm::ELF::R_X86_64_32S: + return visitELF_X86_64_32S(R, Value); + default: + HasError = true; + return RelocToApply(); + } + } + return RelocToApply(); + } + + bool error() { return HasError; } + +private: + llvm::StringRef FileFormat; + bool HasError; + + /// Operations + + // Width is the width in bytes of the extend. + RelocToApply zeroExtend(RelocToApply r, char Width) { + if (Width == r.Width) + return r; + r.Value &= (1 << ((Width * 8))) - 1; + return r; + } + RelocToApply signExtend(RelocToApply r, char Width) { + if (Width == r.Width) + return r; + bool SignBit = r.Value & (1 << ((Width * 8) - 1)); + if (SignBit) { + r.Value |= ~((1 << (Width * 8)) - 1); + } else { + r.Value &= (1 << (Width * 8)) - 1; + } + return r; + } + + /// X86-64 ELF + RelocToApply visitELF_X86_64_NONE(RelocationRef R) { + return RelocToApply(0, 0); + } + RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + return RelocToApply(Value + Addend, 8); + } + RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value, + uint64_t SecAddr) { + int64_t Addend; + R.getAdditionalInfo(Addend); + uint64_t Address; + R.getAddress(Address); + return RelocToApply(Value + Addend - Address, 4); + } + RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + uint32_t Res = (Value + Addend) & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } + RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + int32_t Res = (Value + Addend) & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } +}; + +} +} +#endif diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 1e86980..b326c11 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -16,6 +16,7 @@ #define LLVM_OPERATOR_H #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Instruction.h" #include "llvm/Type.h" @@ -32,9 +33,14 @@ class Operator : public User { private: // Do not implement any of these. The Operator class is intended to be used // as a utility, and is never itself instantiated. - void *operator new(size_t, unsigned); - void *operator new(size_t s); - Operator(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + void *operator new(size_t s) LLVM_DELETED_FUNCTION; + Operator() LLVM_DELETED_FUNCTION; + +protected: + // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete + // an overridden method that's not deleted in the base class. Cannot leave + // this unimplemented because that leads to an ODR-violation. ~Operator(); public: @@ -57,7 +63,6 @@ public: return Instruction::UserOp1; } - static inline bool classof(const Operator *) { return true; } static inline bool classof(const Instruction *) { return true; } static inline bool classof(const ConstantExpr *) { return true; } static inline bool classof(const Value *V) { @@ -77,8 +82,6 @@ public: }; private: - ~OverflowingBinaryOperator(); // do not implement - friend class BinaryOperator; friend class ConstantExpr; void setHasNoUnsignedWrap(bool B) { @@ -103,7 +106,6 @@ public: return (SubclassOptionalData & NoSignedWrap) != 0; } - static inline bool classof(const OverflowingBinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub || @@ -131,8 +133,6 @@ public: }; private: - ~PossiblyExactOperator(); // do not implement - friend class BinaryOperator; friend class ConstantExpr; void setIsExact(bool B) { @@ -167,9 +167,6 @@ public: /// FPMathOperator - Utility class for floating point operations which can have /// information about relaxed accuracy requirements attached to them. class FPMathOperator : public Operator { -private: - ~FPMathOperator(); // do not implement - public: /// \brief Get the maximum error permitted by this operation in ULPs. An @@ -177,7 +174,6 @@ public: /// default precision. float getFPAccuracy() const; - static inline bool classof(const FPMathOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->getType()->isFPOrFPVectorTy(); } @@ -191,11 +187,7 @@ public: /// opcodes. template<typename SuperClass, unsigned Opc> class ConcreteOperator : public SuperClass { - ~ConcreteOperator(); // DO NOT IMPLEMENT public: - static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) { - return true; - } static inline bool classof(const Instruction *I) { return I->getOpcode() == Opc; } @@ -210,45 +202,35 @@ public: class AddOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { - ~AddOperator(); // DO NOT IMPLEMENT }; class SubOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { - ~SubOperator(); // DO NOT IMPLEMENT }; class MulOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { - ~MulOperator(); // DO NOT IMPLEMENT }; class ShlOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { - ~ShlOperator(); // DO NOT IMPLEMENT }; - + class SDivOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { - ~SDivOperator(); // DO NOT IMPLEMENT }; class UDivOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { - ~UDivOperator(); // DO NOT IMPLEMENT }; class AShrOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { - ~AShrOperator(); // DO NOT IMPLEMENT }; class LShrOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { - ~LShrOperator(); // DO NOT IMPLEMENT }; - - - + + + class GEPOperator : public ConcreteOperator<Operator, Instruction::GetElementPtr> { - ~GEPOperator(); // DO NOT IMPLEMENT - enum { IsInBounds = (1 << 0) }; @@ -288,6 +270,12 @@ public: return getPointerOperand()->getType(); } + /// getPointerAddressSpace - Method to return the address space of the + /// pointer operand. + unsigned getPointerAddressSpace() const { + return cast<PointerType>(getPointerOperandType())->getAddressSpace(); + } + unsigned getNumIndices() const { // Note: always non-negative return getNumOperands() - 1; } diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 888537d..cd651db 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -29,6 +29,7 @@ #ifndef LLVM_PASS_H #define LLVM_PASS_H +#include "llvm/Support/Compiler.h" #include <string> namespace llvm { @@ -82,8 +83,8 @@ class Pass { AnalysisResolver *Resolver; // Used to resolve analysis const void *PassID; PassKind Kind; - void operator=(const Pass&); // DO NOT IMPLEMENT - Pass(const Pass &); // DO NOT IMPLEMENT + void operator=(const Pass&) LLVM_DELETED_FUNCTION; + Pass(const Pass &) LLVM_DELETED_FUNCTION; public: explicit Pass(PassKind K, char &pid) : Resolver(0), PassID(&pid), Kind(K) { } diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index 5c6a2d7..d14d73b 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -120,7 +120,7 @@ public: class PMDataManager; class AnalysisResolver { private: - AnalysisResolver(); // DO NOT IMPLEMENT + AnalysisResolver() LLVM_DELETED_FUNCTION; public: explicit AnalysisResolver(PMDataManager &P) : PM(P) { } diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index c50c2cc..c6ad44f 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -126,8 +126,8 @@ public: } private: - void operator=(const PassInfo &); // do not implement - PassInfo(const PassInfo &); // do not implement + void operator=(const PassInfo &) LLVM_DELETED_FUNCTION; + PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION; }; #define CALL_ONCE_INITIALIZATION(function) \ diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index cf71251..d6b0ab8 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -68,24 +68,20 @@ inline unsigned alignOf() { return AlignOf<T>::Alignment; } /// integer literal can be used to specify an alignment constraint. Once built /// up here, we can then begin to indirect between these using normal C++ /// template parameters. -template <size_t Alignment> struct AlignedCharArrayImpl {}; -template <> struct AlignedCharArrayImpl<0> { - typedef char type; -}; +template <size_t Alignment> struct AlignedCharArrayImpl; + +// MSVC requires special handling here. +#ifndef _MSC_VER + #if __has_feature(cxx_alignas) #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ template <> struct AlignedCharArrayImpl<x> { \ - typedef char alignas(x) type; \ + char alignas(x) aligned; \ } -#elif defined(__clang__) || defined(__GNUC__) +#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ template <> struct AlignedCharArrayImpl<x> { \ - typedef char type __attribute__((aligned(x))); \ - } -#elif defined(_MSC_VER) -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template <> struct AlignedCharArrayImpl<x> { \ - typedef __declspec(align(x)) char type; \ + char aligned __attribute__((aligned(x))); \ } #else # error No supported align as directive. @@ -104,9 +100,38 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); + +#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT + +#else // _MSC_VER + +// We provide special variations of this template for the most common +// alignments because __declspec(align(...)) doesn't actually work when it is +// a member of a by-value function argument in MSVC, even if the alignment +// request is something reasonably like 8-byte or 16-byte. +template <> struct AlignedCharArrayImpl<1> { char aligned; }; +template <> struct AlignedCharArrayImpl<2> { short aligned; }; +template <> struct AlignedCharArrayImpl<4> { int aligned; }; +template <> struct AlignedCharArrayImpl<8> { double aligned; }; + +#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ + template <> struct AlignedCharArrayImpl<x> { \ + __declspec(align(x)) char aligned; \ + } +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); // Any larger and MSVC complains. #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT +#endif // _MSC_VER + /// \brief This union template exposes a suitably aligned and sized character /// array member which can hold elements of any of up to four types. /// @@ -134,17 +159,11 @@ public: /// constrain the layout of this character array. char buffer[sizeof(SizerImpl)]; - // Sadly, Clang and GCC both fail to align a character array properly even - // with an explicit alignment attribute. To work around this, we union - // the character array that will actually be used with a struct that contains - // a single aligned character member. Tests seem to indicate that both Clang - // and GCC will properly register the alignment of a struct containing an - // aligned member, and this alignment should carry over to the character - // array in the union. - struct { - typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type - nonce_inner_member; - } nonce_member; +private: + // Tests seem to indicate that both Clang and GCC will properly register the + // alignment of a struct containing an aligned member, and this alignment + // should carry over to the character array in the union. + llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> nonce_member; }; } // end namespace llvm diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index a2ad24f..a644b13 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -79,8 +79,8 @@ class MallocSlabAllocator : public SlabAllocator { public: MallocSlabAllocator() : Allocator() { } virtual ~MallocSlabAllocator(); - virtual MemSlab *Allocate(size_t Size); - virtual void Deallocate(MemSlab *Slab); + virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE; + virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE; }; /// BumpPtrAllocator - This allocator is useful for containers that need @@ -88,8 +88,8 @@ public: /// allocating memory, and never deletes it until the entire block is dead. This /// makes allocation speedy, but must only be used when the trade-off is ok. class BumpPtrAllocator { - BumpPtrAllocator(const BumpPtrAllocator &); // do not implement - void operator=(const BumpPtrAllocator &); // do not implement + BumpPtrAllocator(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION; + void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION; /// SlabSize - Allocate data into slabs of this size unless we get an /// allocation above SizeThreshold. diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index c23bb6a..ad8d6d4 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -81,7 +81,7 @@ public: InstrTy *operator->() const { return I.getPointer(); } operator bool() const { return I.getPointer(); } - /// getCalledValue - Return the pointer to function that is being called... + /// getCalledValue - Return the pointer to function that is being called. /// ValTy *getCalledValue() const { assert(getInstruction() && "Not a call or invoke instruction!"); @@ -95,7 +95,7 @@ public: return dyn_cast<FunTy>(getCalledValue()); } - /// setCalledFunction - Set the callee to the specified value... + /// setCalledFunction - Set the callee to the specified value. /// void setCalledFunction(Value *V) { assert(getInstruction() && "Not a call or invoke instruction!"); @@ -130,7 +130,7 @@ public: } /// arg_iterator - The type of iterator to use when looping over actual - /// arguments at this call site... + /// arguments at this call site. typedef IterTy arg_iterator; /// arg_begin/arg_end - Return iterators corresponding to the actual argument @@ -185,13 +185,13 @@ public: } /// \brief Return true if this function has the given attribute. - bool hasFnAttr(Attributes N) const { - CALLSITE_DELEGATE_GETTER(hasFnAttr(N)); + bool hasFnAttr(Attributes::AttrVal A) const { + CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); } - /// paramHasAttr - whether the call or the callee has the given attribute. - bool paramHasAttr(uint16_t i, Attributes attr) const { - CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr)); + /// \brief Return true if the call or the callee has the given attribute. + bool paramHasAttr(unsigned i, Attributes::AttrVal A) const { + CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); } /// @brief Extract the alignment for a call or parameter (0=unknown). @@ -211,32 +211,32 @@ public: bool doesNotAccessMemory() const { CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); } - void setDoesNotAccessMemory(bool doesNotAccessMemory = true) { - CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory)); + void setDoesNotAccessMemory() { + CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory()); } /// @brief Determine if the call does not access or only reads memory. bool onlyReadsMemory() const { CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); } - void setOnlyReadsMemory(bool onlyReadsMemory = true) { - CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory)); + void setOnlyReadsMemory() { + CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory()); } /// @brief Determine if the call cannot return. bool doesNotReturn() const { CALLSITE_DELEGATE_GETTER(doesNotReturn()); } - void setDoesNotReturn(bool doesNotReturn = true) { - CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn)); + void setDoesNotReturn() { + CALLSITE_DELEGATE_SETTER(setDoesNotReturn()); } /// @brief Determine if the call cannot unwind. bool doesNotThrow() const { CALLSITE_DELEGATE_GETTER(doesNotThrow()); } - void setDoesNotThrow(bool doesNotThrow = true) { - CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow)); + void setDoesNotThrow() { + CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); } #undef CALLSITE_DELEGATE_GETTER @@ -244,12 +244,12 @@ public: /// @brief Determine whether this argument is not captured. bool doesNotCapture(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::NoCapture); + return paramHasAttr(ArgNo + 1, Attributes::NoCapture); } /// @brief Determine whether this argument is passed by value. bool isByValArgument(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ByVal); + return paramHasAttr(ArgNo + 1, Attributes::ByVal); } /// hasArgument - Returns true if this CallSite passes the given Value* as an diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 3aab436..0c71882 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_CASTING_H #define LLVM_SUPPORT_CASTING_H +#include "llvm/Support/type_traits.h" #include <cassert> namespace llvm { @@ -44,13 +45,23 @@ template<typename From> struct simplify_type<const From> { // The core of the implementation of isa<X> is here; To and From should be // the names of classes. This template can be specialized to customize the // implementation of isa<> without rewriting it from scratch. -template <typename To, typename From> +template <typename To, typename From, typename Enabler = void> struct isa_impl { static inline bool doit(const From &Val) { return To::classof(&Val); } }; +/// \brief Always allow upcasts, and perform no dynamic check for them. +template <typename To, typename From> +struct isa_impl<To, From, + typename llvm::enable_if_c< + llvm::is_base_of<To, From>::value + >::type + > { + static inline bool doit(const From &) { return true; } +}; + template <typename To, typename From> struct isa_impl_cl { static inline bool doit(const From &Val) { return isa_impl<To, From>::doit(Val); @@ -65,18 +76,21 @@ template <typename To, typename From> struct isa_impl_cl<To, const From> { template <typename To, typename From> struct isa_impl_cl<To, From*> { static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); return isa_impl<To, From>::doit(*Val); } }; template <typename To, typename From> struct isa_impl_cl<To, const From*> { static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); return isa_impl<To, From>::doit(*Val); } }; template <typename To, typename From> struct isa_impl_cl<To, const From*const> { static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); return isa_impl<To, From>::doit(*Val); } }; diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index ae1570d..872c579 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -41,16 +41,14 @@ namespace cl { // ParseCommandLineOptions - Command line option processing entry point. // void ParseCommandLineOptions(int argc, const char * const *argv, - const char *Overview = 0, - bool ReadResponseFiles = false); + const char *Overview = 0); //===----------------------------------------------------------------------===// // ParseEnvironmentOptions - Environment variable option processing alternate // entry point. // void ParseEnvironmentOptions(const char *progName, const char *envvar, - const char *Overview = 0, - bool ReadResponseFiles = false); + const char *Overview = 0); ///===---------------------------------------------------------------------===// /// SetVersionPrinter - Override the default (LLVM specific) version printer @@ -1509,7 +1507,7 @@ class bits : public Option, public bits_storage<DataType, Storage> { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - addValue(Val); + this->addValue(Val); setPosition(pos); Positions.push_back(pos); return false; @@ -1608,15 +1606,16 @@ public: class alias : public Option { Option *AliasFor; virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, - StringRef Arg) { + StringRef Arg) LLVM_OVERRIDE { return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); } // Handle printing stuff... - virtual size_t getOptionWidth() const; - virtual void printOptionInfo(size_t GlobalWidth) const; + virtual size_t getOptionWidth() const LLVM_OVERRIDE; + virtual void printOptionInfo(size_t GlobalWidth) const LLVM_OVERRIDE; // Aliases do not need to print their values. - virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + virtual void printOptionValue(size_t /*GlobalWidth*/, + bool /*Force*/) const LLVM_OVERRIDE {} void done() { if (!hasArgStr()) diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 4469ae3..7ceeb32 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -24,7 +24,7 @@ /// does not imply the existence of any other C++ library features. #if (__has_feature(cxx_rvalue_references) \ || defined(__GXX_EXPERIMENTAL_CXX0X__) \ - || _MSC_VER >= 1600) + || (defined(_MSC_VER) && _MSC_VER >= 1600)) #define LLVM_USE_RVALUE_REFERENCES 1 #else #define LLVM_USE_RVALUE_REFERENCES 0 @@ -40,7 +40,7 @@ /// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it. /// Use to mark functions as uncallable. Member functions with this should -/// be declared private so that some behaivor is kept in C++03 mode. +/// be declared private so that some behavior is kept in C++03 mode. /// /// class DontCopy { /// private: @@ -57,6 +57,22 @@ #define LLVM_DELETED_FUNCTION #endif +/// LLVM_FINAL - Expands to 'final' if the compiler supports it. +/// Use to mark classes or virtual methods as final. +#if (__has_feature(cxx_override_control)) +#define LLVM_FINAL final +#else +#define LLVM_FINAL +#endif + +/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it. +/// Use to mark virtual methods as overriding a base class method. +#if (__has_feature(cxx_override_control)) +#define LLVM_OVERRIDE override +#else +#define LLVM_OVERRIDE +#endif + /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked /// into a shared library, then the class should be private to the library and /// not accessible from outside it. Can also be used to mark variables and @@ -106,9 +122,11 @@ #endif #if (__GNUC__ >= 4) -#define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE)) +#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) +#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) #else -#define BUILTIN_EXPECT(EXPR, VALUE) (EXPR) +#define LLVM_LIKELY(EXPR) (EXPR) +#define LLVM_UNLIKELY(EXPR) (EXPR) #endif @@ -187,4 +205,13 @@ # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #endif +// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression +// which causes the program to exit abnormally. +#if defined(__clang__) || (__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define LLVM_BUILTIN_TRAP __builtin_trap() +#else +# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 +#endif + #endif diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h index 506ec96..a3ae782 100644 --- a/include/llvm/Support/DataExtractor.h +++ b/include/llvm/Support/DataExtractor.h @@ -10,6 +10,7 @@ #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H #define LLVM_SUPPORT_DATAEXTRACTOR_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -99,8 +100,8 @@ public: /// enough bytes to extract this value, the offset will be left /// unmodified. /// - /// @param[in] byte_size - /// The size in byte of the integer to extract. + /// @param[in] size + /// The size in bytes of the integer to extract. /// /// @return /// The sign extended signed integer value that was extracted, diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index f7ae60f..2cd2671 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -441,6 +441,7 @@ enum { R_MICROBLAZE_COPY = 21 }; +// ELF Relocation types for PPC32 enum { R_PPC_NONE = 0, /* No relocation. */ R_PPC_ADDR32 = 1, @@ -456,7 +457,23 @@ enum { R_PPC_REL14 = 11, R_PPC_REL14_BRTAKEN = 12, R_PPC_REL14_BRNTAKEN = 13, - R_PPC_REL32 = 26 + R_PPC_REL32 = 26, + R_PPC_TPREL16_LO = 70, + R_PPC_TPREL16_HA = 72 +}; + +// ELF Relocation types for PPC64 +enum { + R_PPC64_ADDR16_LO = 4, + R_PPC64_ADDR16_HI = 5, + R_PPC64_ADDR14 = 7, + R_PPC64_REL24 = 10, + R_PPC64_ADDR64 = 38, + R_PPC64_ADDR16_HIGHER = 39, + R_PPC64_ADDR16_HIGHEST = 41, + R_PPC64_TOC16 = 47, + R_PPC64_TOC = 51, + R_PPC64_TOC16_DS = 63 }; // ARM Specific e_flags @@ -674,8 +691,36 @@ enum { R_MIPS_NUM = 218 }; +// Hexagon Specific e_flags +// Release 5 ABI +enum { + // Object processor version flags, bits[3:0] + EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2 + EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3 + EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4 + EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5 + + // Highest ISA version flags + EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[3:0] + // of e_flags + EF_HEXAGON_ISA_V2 = 0x00000010, // Hexagon V2 ISA + EF_HEXAGON_ISA_V3 = 0x00000020, // Hexagon V3 ISA + EF_HEXAGON_ISA_V4 = 0x00000030, // Hexagon V4 ISA + EF_HEXAGON_ISA_V5 = 0x00000040 // Hexagon V5 ISA +}; + +// Hexagon specific Section indexes for common small data +// Release 5 ABI +enum { + SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes + SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access + SHN_HEXAGON_SCOMMON_2 = 0xff02, // Half-word-sized access + SHN_HEXAGON_SCOMMON_4 = 0xff03, // Word-sized access + SHN_HEXAGON_SCOMMON_8 = 0xff04 // Double-word-size access +}; + // ELF Relocation types for Hexagon -// Release 5 ABI - Document: 80-V9418-3 Rev. J +// Release 5 ABI enum { R_HEX_NONE = 0, R_HEX_B22_PCREL = 1, @@ -1103,6 +1148,9 @@ enum { PT_PHDR = 6, // The program header table itself. PT_TLS = 7, // The thread-local storage template. PT_LOOS = 0x60000000, // Lowest operating system-specific pt entry type. + PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type. + PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type. + PT_HIPROC = 0x7fffffff, // Highest processor-specific program hdr entry type. // x86-64 program header types. // These all contain stack unwind tables. @@ -1113,9 +1161,11 @@ enum { PT_GNU_STACK = 0x6474e551, // Indicates stack executability. PT_GNU_RELRO = 0x6474e552, // Read-only after relocation. - PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type. - PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type. - PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type. + // ARM program header types. + PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility information + // These all contain stack unwind tables. + PT_ARM_EXIDX = 0x70000001, + PT_ARM_UNWIND = 0x70000001 }; // Segment flag bits. diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h index 0f07164..bcd35e3 100644 --- a/include/llvm/Support/FileOutputBuffer.h +++ b/include/llvm/Support/FileOutputBuffer.h @@ -78,10 +78,11 @@ public: ~FileOutputBuffer(); +private: + FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; + FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; protected: - FileOutputBuffer(const FileOutputBuffer &); // DO NOT IMPLEMENT - FileOutputBuffer &operator=(const FileOutputBuffer &); // DO NOT IMPLEMENT - FileOutputBuffer(uint8_t *Start, uint8_t *End, + FileOutputBuffer(uint8_t *Start, uint8_t *End, StringRef Path, StringRef TempPath); uint8_t *BufferStart; diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index f4a9aa0..b455b28 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -40,7 +40,7 @@ #include <string> #include <vector> -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif @@ -280,7 +280,7 @@ error_code create_symlink(const Twine &to, const Twine &from); /// @brief Get the current path. /// /// @param result Holds the current path on return. -/// @results errc::success if the current path has been stored in result, +/// @returns errc::success if the current path has been stored in result, /// otherwise a platform specific error_code. error_code current_path(SmallVectorImpl<char> &result); @@ -289,7 +289,7 @@ error_code current_path(SmallVectorImpl<char> &result); /// @param path Input path. /// @param existed Set to true if \a path existed, false if it did not. /// undefined otherwise. -/// @results errc::success if path has been removed and existed has been +/// @returns errc::success if path has been removed and existed has been /// successfully set, otherwise a platform specific error_code. error_code remove(const Twine &path, bool &existed); @@ -298,7 +298,7 @@ error_code remove(const Twine &path, bool &existed); /// /// @param path Input path. /// @param num_removed Number of files removed. -/// @results errc::success if path has been removed and num_removed has been +/// @returns errc::success if path has been removed and num_removed has been /// successfully set, otherwise a platform specific error_code. error_code remove_all(const Twine &path, uint32_t &num_removed); @@ -323,7 +323,7 @@ error_code resize_file(const Twine &path, uint64_t size); /// @brief Does file exist? /// /// @param status A file_status previously returned from stat. -/// @results True if the file represented by status exists, false if it does +/// @returns True if the file represented by status exists, false if it does /// not. bool exists(file_status status); @@ -332,7 +332,7 @@ bool exists(file_status status); /// @param path Input path. /// @param result Set to true if the file represented by status exists, false if /// it does not. Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code exists(const Twine &path, bool &result); @@ -350,7 +350,7 @@ inline bool exists(const Twine &path) { /// /// assert(status_known(A) || status_known(B)); /// -/// @results True if A and B both represent the same file system entity, false +/// @returns True if A and B both represent the same file system entity, false /// otherwise. bool equivalent(file_status A, file_status B); @@ -362,7 +362,7 @@ bool equivalent(file_status A, file_status B); /// @param B Input path B. /// @param result Set to true if stat(A) and stat(B) have the same device and /// inode (or equivalent). -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code equivalent(const Twine &A, const Twine &B, bool &result); @@ -384,7 +384,7 @@ error_code file_size(const Twine &path, uint64_t &result); /// @brief Does status represent a directory? /// /// @param status A file_status previously returned from status. -/// @results status.type() == file_type::directory_file. +/// @returns status.type() == file_type::directory_file. bool is_directory(file_status status); /// @brief Is path a directory? @@ -392,14 +392,14 @@ bool is_directory(file_status status); /// @param path Input path. /// @param result Set to true if \a path is a directory, false if it is not. /// Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code is_directory(const Twine &path, bool &result); /// @brief Does status represent a regular file? /// /// @param status A file_status previously returned from status. -/// @results status_known(status) && status.type() == file_type::regular_file. +/// @returns status_known(status) && status.type() == file_type::regular_file. bool is_regular_file(file_status status); /// @brief Is path a regular file? @@ -407,7 +407,7 @@ bool is_regular_file(file_status status); /// @param path Input path. /// @param result Set to true if \a path is a regular file, false if it is not. /// Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code is_regular_file(const Twine &path, bool &result); @@ -415,7 +415,7 @@ error_code is_regular_file(const Twine &path, bool &result); /// directory, regular file, or symlink? /// /// @param status A file_status previously returned from status. -/// @results exists(s) && !is_regular_file(s) && !is_directory(s) && +/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) && /// !is_symlink(s) bool is_other(file_status status); @@ -425,14 +425,14 @@ bool is_other(file_status status); /// @param path Input path. /// @param result Set to true if \a path exists, but is not a directory, regular /// file, or a symlink, false if it does not. Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code is_other(const Twine &path, bool &result); /// @brief Does status represent a symlink? /// /// @param status A file_status previously returned from stat. -/// @param result status.type() == symlink_file. +/// @returns status.type() == symlink_file. bool is_symlink(file_status status); /// @brief Is path a symlink? @@ -440,7 +440,7 @@ bool is_symlink(file_status status); /// @param path Input path. /// @param result Set to true if \a path is a symlink, false if it is not. /// Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code is_symlink(const Twine &path, bool &result); @@ -448,28 +448,28 @@ error_code is_symlink(const Twine &path, bool &result); /// /// @param path Input path. /// @param result Set to the file status. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code status(const Twine &path, file_status &result); /// @brief Modifies permission bits on a file /// /// @param path Input path. -/// @results errc::success if permissions have been changed, otherwise a +/// @returns errc::success if permissions have been changed, otherwise a /// platform specific error_code. error_code permissions(const Twine &path, perms prms); /// @brief Is status available? /// -/// @param path Input path. -/// @results True if status() != status_error. +/// @param s Input file status. +/// @returns True if status() != status_error. bool status_known(file_status s); /// @brief Is status available? /// /// @param path Input path. /// @param result Set to true if status() != status_error. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code status_known(const Twine &path, bool &result); @@ -486,11 +486,11 @@ error_code status_known(const Twine &path, bool &result); /// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s /// /// @param model Name to base unique path off of. -/// @param result_fs Set to the opened file's file descriptor. +/// @param result_fd Set to the opened file's file descriptor. /// @param result_path Set to the opened file's absolute path. -/// @param makeAbsolute If true and @model is not an absolute path, a temp +/// @param makeAbsolute If true and \a model is not an absolute path, a temp /// directory will be prepended. -/// @results errc::success if result_{fd,path} have been successfully set, +/// @returns errc::success if result_{fd,path} have been successfully set, /// otherwise a platform specific error_code. error_code unique_file(const Twine &model, int &result_fd, SmallVectorImpl<char> &result_path, @@ -503,7 +503,7 @@ error_code unique_file(const Twine &model, int &result_fd, /// /// @param path Input path. /// @param result Set to the canonicalized version of \a path. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result); @@ -511,7 +511,7 @@ error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result); /// /// @param path Input path. /// @param magic Byte sequence to compare \a path's first len(magic) bytes to. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code has_magic(const Twine &path, const Twine &magic, bool &result); @@ -522,7 +522,7 @@ error_code has_magic(const Twine &path, const Twine &magic, bool &result); /// @param result Set to the first \a len bytes in the file pointed to by /// \a path. Or the entire file if file_size(path) < len, in which /// case result.size() returns the size of the file. -/// @results errc::success if result has been successfully set, +/// @returns errc::success if result has been successfully set, /// errc::value_too_large if len is larger then the file pointed to by /// \a path, otherwise a platform specific error_code. error_code get_magic(const Twine &path, uint32_t len, @@ -535,14 +535,14 @@ file_magic identify_magic(StringRef magic); /// /// @param path Input path. /// @param result Set to the type of file, or LLVMFileType::Unknown_FileType. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code identify_magic(const Twine &path, file_magic &result); /// @brief Get library paths the system linker uses. /// /// @param result Set to the list of system library paths. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result); @@ -550,7 +550,7 @@ error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result); /// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR. /// /// @param result Set to the list of bitcode library paths. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result); @@ -563,7 +563,7 @@ error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result); /// /// @param short_name Library name one would give to the system linker. /// @param result Set to the absolute path \a short_name represents. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result); @@ -572,7 +572,7 @@ error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result); /// @param argv0 The program name as it was spelled on the command line. /// @param MainAddr Address of some symbol in the executable (not in a library). /// @param result Set to the absolute path of the current executable. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code GetMainExecutable(const char *argv0, void *MainAddr, SmallVectorImpl<char> &result); @@ -586,9 +586,9 @@ class mapped_file_region { public: enum mapmode { - readonly, //< May only access map via const_data as read only. - readwrite, //< May access map via data and modify it. Written to path. - priv //< May modify via data, but changes are lost on destruction. + readonly, ///< May only access map via const_data as read only. + readwrite, ///< May access map via data and modify it. Written to path. + priv ///< May modify via data, but changes are lost on destruction. }; private: @@ -596,7 +596,7 @@ private: mapmode Mode; uint64_t Size; void *Mapping; -#if LLVM_ON_WIN32 +#ifdef LLVM_ON_WIN32 int FileDescriptor; void *FileHandle; void *FileMappingHandle; @@ -658,13 +658,13 @@ public: /// /// @param path Path to file to map. /// @param file_offset Byte offset in file where mapping should begin. -/// @param size_t Byte length of range of the file to map. +/// @param size Byte length of range of the file to map. /// @param map_writable If true, the file will be mapped in r/w such /// that changes to the mapped buffer will be flushed back /// to the file. If false, the file will be mapped read-only /// and the buffer will be read-only. /// @param result Set to the start address of the mapped buffer. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, bool map_writable, void *&result); @@ -674,7 +674,7 @@ error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, /// /// @param base Pointer to the start of the buffer. /// @param size Byte length of the range to unmmap. -/// @results errc::success if result has been successfully set, otherwise a +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code unmap_file_pages(void *base, size_t size); diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index 59812d9..aaa54e1 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -170,31 +170,47 @@ public: } }; -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template <typename T> inline format_object1<T> format(const char *Fmt, const T &Val) { return format_object1<T>(Fmt, Val); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template <typename T1, typename T2> inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1, const T2 &Val2) { return format_object2<T1, T2>(Fmt, Val1, Val2); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template <typename T1, typename T2, typename T3> inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3) { return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template <typename T1, typename T2, typename T3, typename T4> inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3, @@ -202,8 +218,12 @@ inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template <typename T1, typename T2, typename T3, typename T4, typename T5> inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, const T2 &Val2, const T3 &Val3, diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index 58a1885..21635dc 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -55,14 +55,15 @@ namespace llvm /// const char *Scanned; - virtual void write_impl(const char *Ptr, size_t Size); + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, /// not counting the bytes currently in the buffer. - virtual uint64_t current_pos() const { - // This has the same effect as calling TheStream.current_pos(), - // but that interface is private. - return TheStream->tell() - TheStream->GetNumBytesInBuffer(); + virtual uint64_t current_pos() const LLVM_OVERRIDE { + // Our current position in the stream is all the contents which have been + // written to the underlying stream (*not* the current position of the + // underlying stream). + return TheStream->tell(); } /// ComputeColumn - Examine the given output buffer and figure out which diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 19e1ce8..e552315 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -27,13 +27,15 @@ class GCOVBlock; class GCOVLines; class FileInfo; -enum GCOVFormat { - InvalidGCOV, - GCNO_402, - GCNO_404, - GCDA_402, - GCDA_404 -}; +namespace GCOV { + enum GCOVFormat { + InvalidGCOV, + GCNO_402, + GCNO_404, + GCDA_402, + GCDA_404 + }; +} // end GCOV namespace /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific /// read operations. @@ -42,20 +44,20 @@ public: GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} /// readGCOVFormat - Read GCOV signature at the beginning of buffer. - enum GCOVFormat readGCOVFormat() { + GCOV::GCOVFormat readGCOVFormat() { StringRef Magic = Buffer->getBuffer().slice(0, 12); Cursor = 12; if (Magic == "oncg*404MVLL") - return GCNO_404; + return GCOV::GCNO_404; else if (Magic == "oncg*204MVLL") - return GCNO_402; + return GCOV::GCNO_402; else if (Magic == "adcg*404MVLL") - return GCDA_404; + return GCOV::GCDA_404; else if (Magic == "adcg*204MVLL") - return GCDA_402; + return GCOV::GCDA_402; Cursor = 0; - return InvalidGCOV; + return GCOV::InvalidGCOV; } /// readFunctionTag - If cursor points to a function tag then increment the @@ -128,7 +130,7 @@ public: StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); assert (Str.empty() == false && "Unexpected memory buffer end!"); Cursor += 4; - Result = *(uint32_t *)(Str.data()); + Result = *(const uint32_t *)(Str.data()); return Result; } @@ -170,7 +172,7 @@ class GCOVFunction { public: GCOVFunction() : Ident(0), LineNumber(0) {} ~GCOVFunction(); - bool read(GCOVBuffer &Buffer, GCOVFormat Format); + bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format); void dump(); void collectLineCounts(FileInfo &FI); private: diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 109b3cf..6dfb4de 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -209,6 +209,9 @@ public: RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); } RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); } RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); } + RetTy visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); } + RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); } + RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); } RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); } // Call and Invoke are slightly different as they delegate first through @@ -262,6 +265,9 @@ private: case Intrinsic::memcpy: DELEGATE(MemCpyInst); case Intrinsic::memmove: DELEGATE(MemMoveInst); case Intrinsic::memset: DELEGATE(MemSetInst); + case Intrinsic::vastart: DELEGATE(VAStartInst); + case Intrinsic::vaend: DELEGATE(VAEndInst); + case Intrinsic::vacopy: DELEGATE(VACopyInst); case Intrinsic::not_intrinsic: break; } } diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h index bb9e769..03039fd 100644 --- a/include/llvm/Support/IntegersSubset.h +++ b/include/llvm/Support/IntegersSubset.h @@ -411,8 +411,8 @@ public: unsigned getSize() const { APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0); for (unsigned i = 0, e = getNumItems(); i != e; ++i) { - const APInt &Low = getItem(i).getLow(); - const APInt &High = getItem(i).getHigh(); + const APInt Low = getItem(i).getLow(); + const APInt High = getItem(i).getHigh(); APInt S = High - Low + 1; sz += S; } @@ -426,8 +426,8 @@ public: APInt getSingleValue(unsigned idx) const { APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0); for (unsigned i = 0, e = getNumItems(); i != e; ++i) { - const APInt &Low = getItem(i).getLow(); - const APInt &High = getItem(i).getHigh(); + const APInt Low = getItem(i).getLow(); + const APInt High = getItem(i).getHigh(); APInt S = High - Low + 1; APInt oldSz = sz; sz += S; diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h index cab18dc..7635d5e 100644 --- a/include/llvm/Support/IntegersSubsetMapping.h +++ b/include/llvm/Support/IntegersSubsetMapping.h @@ -42,6 +42,7 @@ public: struct RangeEx : public RangeTy { RangeEx() : Weight(1) {} RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {} + RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {} RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {} RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {} RangeEx(const IntTy &L, const IntTy &H, unsigned W) : @@ -316,13 +317,13 @@ public: Items.clear(); const IntTy *Low = &OldItems.begin()->first.getLow(); const IntTy *High = &OldItems.begin()->first.getHigh(); - unsigned Weight = 1; + unsigned Weight = OldItems.begin()->first.Weight; SuccessorClass *Successor = OldItems.begin()->second; for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end(); j != e; i = j++) { if (isJoinable(i, j)) { const IntTy *CurHigh = &j->first.getHigh(); - ++Weight; + Weight += j->first.Weight; if (*CurHigh > *High) High = CurHigh; } else { @@ -330,7 +331,7 @@ public: add(R, Successor); Low = &j->first.getLow(); High = &j->first.getHigh(); - Weight = 1; + Weight = j->first.Weight; Successor = j->second; } } @@ -362,10 +363,17 @@ public: /// Adds all ranges and values from given ranges set to the current /// mapping. - void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0) { + void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0, + unsigned Weight = 0) { + unsigned ItemWeight = 1; + if (Weight) + // Weight is associated with CRS, for now we perform a division to + // get the weight for each item. + ItemWeight = Weight / CRS.getNumItems(); for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) { RangeTy R = CRS.getItem(i); - add(R, S); + RangeEx REx(R, ItemWeight); + add(REx, S); } } diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h index 410edd4..b52e5bc 100644 --- a/include/llvm/Support/LEB128.h +++ b/include/llvm/Support/LEB128.h @@ -15,7 +15,7 @@ #ifndef LLVM_SYSTEM_LEB128_H #define LLVM_SYSTEM_LEB128_H -#include <llvm/Support/raw_ostream.h> +#include "llvm/Support/raw_ostream.h" namespace llvm { diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h index e2fa8eb..8c4a760 100644 --- a/include/llvm/Support/LockFileManager.h +++ b/include/llvm/Support/LockFileManager.h @@ -47,8 +47,8 @@ private: Optional<std::pair<std::string, int> > Owner; Optional<error_code> Error; - LockFileManager(const LockFileManager &); - LockFileManager &operator=(const LockFileManager &); + LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION; + LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION; static Optional<std::pair<std::string, int> > readLockFile(StringRef LockFileName); diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 4005161..11f9e63 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -431,21 +431,22 @@ inline uint64_t NextPowerOf2(uint64_t A) { return A + 1; } -/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is -/// greater than or equal to \arg Value and is a multiple of \arg -/// Align. Align must be non-zero. +/// Returns the next integer (mod 2**64) that is greater than or equal to +/// \p Value and is a multiple of \p Align. \p Align must be non-zero. /// /// Examples: -/// RoundUpToAlignment(5, 8) = 8 -/// RoundUpToAlignment(17, 8) = 24 -/// RoundUpToAlignment(~0LL, 8) = 0 +/// \code +/// RoundUpToAlignment(5, 8) = 8 +/// RoundUpToAlignment(17, 8) = 24 +/// RoundUpToAlignment(~0LL, 8) = 0 +/// \endcode inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) { return ((Value + Align - 1) / Align) * Align; } -/// OffsetToAlignment - Return the offset to the next integer (mod 2**64) that -/// is greater than or equal to \arg Value and is a multiple of \arg -/// Align. Align must be non-zero. +/// Returns the offset to the next integer (mod 2**64) that is greater than +/// or equal to \p Value and is a multiple of \p Align. \p Align must be +/// non-zero. inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { return RoundUpToAlignment(Value, Align) - Value; } @@ -463,12 +464,24 @@ template <unsigned B> inline int32_t SignExtend32(uint32_t x) { return int32_t(x << (32 - B)) >> (32 - B); } +/// \brief Sign extend number in the bottom B bits of X to a 32-bit int. +/// Requires 0 < B <= 32. +inline int32_t SignExtend32(uint32_t X, unsigned B) { + return int32_t(X << (32 - B)) >> (32 - B); +} + /// SignExtend64 - Sign extend B-bit number x to 64-bit int. /// Usage int64_t r = SignExtend64<5>(x); template <unsigned B> inline int64_t SignExtend64(uint64_t x) { return int64_t(x << (64 - B)) >> (64 - B); } +/// \brief Sign extend number in the bottom B bits of X to a 64-bit int. +/// Requires 0 < B <= 64. +inline int64_t SignExtend64(uint64_t X, unsigned B) { + return int64_t(X << (64 - B)) >> (64 - B); +} + } // End llvm namespace #endif diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h index 37890e7..025eee7 100644 --- a/include/llvm/Support/Memory.h +++ b/include/llvm/Support/Memory.h @@ -15,6 +15,7 @@ #define LLVM_SYSTEM_MEMORY_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/system_error.h" #include <string> namespace llvm { @@ -43,6 +44,70 @@ namespace sys { /// @brief An abstraction for memory operations. class Memory { public: + enum ProtectionFlags { + MF_READ = 0x1000000, + MF_WRITE = 0x2000000, + MF_EXEC = 0x4000000 + }; + + /// This method allocates a block of memory that is suitable for loading + /// dynamically generated code (e.g. JIT). An attempt to allocate + /// \p NumBytes bytes of virtual memory is made. + /// \p NearBlock may point to an existing allocation in which case + /// an attempt is made to allocate more memory near the existing block. + /// The actual allocated address is not guaranteed to be near the requested + /// address. + /// \p Flags is used to set the initial protection flags for the block + /// of the memory. + /// \p EC [out] returns an object describing any error that occurs. + /// + /// This method may allocate more than the number of bytes requested. The + /// actual number of bytes allocated is indicated in the returned + /// MemoryBlock. + /// + /// The start of the allocated block must be aligned with the + /// system allocation granularity (64K on Windows, page size on Linux). + /// If the address following \p NearBlock is not so aligned, it will be + /// rounded up to the next allocation granularity boundary. + /// + /// \r a non-null MemoryBlock if the function was successful, + /// otherwise a null MemoryBlock is with \p EC describing the error. + /// + /// @brief Allocate mapped memory. + static MemoryBlock allocateMappedMemory(size_t NumBytes, + const MemoryBlock *const NearBlock, + unsigned Flags, + error_code &EC); + + /// This method releases a block of memory that was allocated with the + /// allocateMappedMemory method. It should not be used to release any + /// memory block allocated any other way. + /// \p Block describes the memory to be released. + /// + /// \r error_success if the function was successful, or an error_code + /// describing the failure if an error occurred. + /// + /// @brief Release mapped memory. + static error_code releaseMappedMemory(MemoryBlock &Block); + + /// This method sets the protection flags for a block of memory to the + /// state specified by /p Flags. The behavior is not specified if the + /// memory was not allocated using the allocateMappedMemory method. + /// \p Block describes the memory block to be protected. + /// \p Flags specifies the new protection state to be assigned to the block. + /// \p ErrMsg [out] returns a string describing any error that occured. + /// + /// If \p Flags is MF_WRITE, the actual behavior varies + /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the + /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386). + /// + /// \r error_success if the function was successful, or an error_code + /// describing the failure if an error occurred. + /// + /// @brief Set memory protection state. + static error_code protectMappedMemory(const MemoryBlock &Block, + unsigned Flags); + /// This method allocates a block of Read/Write/Execute memory that is /// suitable for executing dynamically generated code (e.g. JIT). An /// attempt to allocate \p NumBytes bytes of virtual memory is made. diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 06816de..1f02907 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_MEMORYBUFFER_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -36,8 +37,8 @@ class MemoryBuffer { const char *BufferStart; // Start of the buffer. const char *BufferEnd; // End of the buffer. - MemoryBuffer(const MemoryBuffer &); // DO NOT IMPLEMENT - MemoryBuffer &operator=(const MemoryBuffer &); // DO NOT IMPLEMENT + MemoryBuffer(const MemoryBuffer &) LLVM_DELETED_FUNCTION; + MemoryBuffer &operator=(const MemoryBuffer &) LLVM_DELETED_FUNCTION; protected: MemoryBuffer() {} void init(const char *BufStart, const char *BufEnd, diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h index 42ea630..6abc533 100644 --- a/include/llvm/Support/Mutex.h +++ b/include/llvm/Support/Mutex.h @@ -14,6 +14,7 @@ #ifndef LLVM_SYSTEM_MUTEX_H #define LLVM_SYSTEM_MUTEX_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/Threading.h" #include <cassert> @@ -75,8 +76,8 @@ namespace llvm /// @name Do Not Implement /// @{ private: - MutexImpl(const MutexImpl & original); - void operator=(const MutexImpl &); + MutexImpl(const MutexImpl &) LLVM_DELETED_FUNCTION; + void operator=(const MutexImpl &) LLVM_DELETED_FUNCTION; /// @} }; diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h index cd13bfe..6bb1622 100644 --- a/include/llvm/Support/MutexGuard.h +++ b/include/llvm/Support/MutexGuard.h @@ -26,8 +26,8 @@ namespace llvm { /// @brief Guard a section of code with a Mutex. class MutexGuard { sys::Mutex &M; - MutexGuard(const MutexGuard &); // DO NOT IMPLEMENT - void operator=(const MutexGuard &); // DO NOT IMPLEMENT + MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION; + void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION; public: MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); } ~MutexGuard() { M.release(); } diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h index f4bedf9..643ee8c 100644 --- a/include/llvm/Support/PathV1.h +++ b/include/llvm/Support/PathV1.h @@ -683,8 +683,8 @@ namespace sys { /// This function returns status information about the file. The type of /// path (file or directory) is updated to reflect the actual contents /// of the file system. - /// @returns 0 on failure, with Error explaining why (if non-zero) - /// @returns a pointer to a FileStatus structure on success. + /// @returns 0 on failure, with Error explaining why (if non-zero), + /// otherwise returns a pointer to a FileStatus structure on success. /// @brief Get file status. const FileStatus *getFileStatus( bool forceUpdate = false, ///< Force an update from the file system diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h index 8d79709..ae1a21c 100644 --- a/include/llvm/Support/PathV2.h +++ b/include/llvm/Support/PathV2.h @@ -39,13 +39,14 @@ namespace path { /// The backwards traversal order is the reverse of forward traversal. /// /// Iteration examples. Each component is separated by ',': -/// / => / -/// /foo => /,foo -/// foo/ => foo,. -/// /foo/bar => /,foo,bar -/// ../ => ..,. -/// C:\foo\bar => C:,/,foo,bar -/// +/// @code +/// / => / +/// /foo => /,foo +/// foo/ => foo,. +/// /foo/bar => /,foo,bar +/// ../ => ..,. +/// C:\foo\bar => C:,/,foo,bar +/// @endcode class const_iterator { StringRef Path; ///< The entire path. StringRef Component; ///< The current component. Not necessarily in Path. @@ -107,18 +108,22 @@ inline reverse_iterator rend(StringRef path) { /// @brief Remove the last component from \a path unless it is the root dir. /// -/// directory/filename.cpp => directory/ -/// directory/ => directory -/// / => / +/// @code +/// directory/filename.cpp => directory/ +/// directory/ => directory +/// / => / +/// @endcode /// /// @param path A path that is modified to not have a file component. void remove_filename(SmallVectorImpl<char> &path); /// @brief Replace the file extension of \a path with \a extension. /// -/// ./filename.cpp => ./filename.extension -/// ./filename => ./filename.extension -/// ./ => ./.extension +/// @code +/// ./filename.cpp => ./filename.extension +/// ./filename => ./filename.extension +/// ./ => ./.extension +/// @endcode /// /// @param path A path that has its extension replaced with \a extension. /// @param extension The extension to be added. It may be empty. It may also @@ -128,12 +133,14 @@ void replace_extension(SmallVectorImpl<char> &path, const Twine &extension); /// @brief Append to path. /// -/// /foo + bar/f => /foo/bar/f -/// /foo/ + bar/f => /foo/bar/f -/// foo + bar/f => foo/bar/f +/// @code +/// /foo + bar/f => /foo/bar/f +/// /foo/ + bar/f => /foo/bar/f +/// foo + bar/f => foo/bar/f +/// @endcode /// /// @param path Set to \a path + \a component. -/// @param component The component to be appended to \a path. +/// @param a The component to be appended to \a path. void append(SmallVectorImpl<char> &path, const Twine &a, const Twine &b = "", const Twine &c = "", @@ -141,9 +148,11 @@ void append(SmallVectorImpl<char> &path, const Twine &a, /// @brief Append to path. /// -/// /foo + [bar,f] => /foo/bar/f -/// /foo/ + [bar,f] => /foo/bar/f -/// foo + [bar,f] => foo/bar/f +/// @code +/// /foo + [bar,f] => /foo/bar/f +/// /foo/ + [bar,f] => /foo/bar/f +/// foo + [bar,f] => foo/bar/f +/// @endcode /// /// @param path Set to \a path + [\a begin, \a end). /// @param begin Start of components to append. @@ -169,9 +178,11 @@ void native(const Twine &path, SmallVectorImpl<char> &result); /// @brief Get root name. /// -/// //net/hello => //net -/// c:/hello => c: (on Windows, on other platforms nothing) -/// /hello => <empty> +/// @code +/// //net/hello => //net +/// c:/hello => c: (on Windows, on other platforms nothing) +/// /hello => <empty> +/// @endcode /// /// @param path Input path. /// @result The root name of \a path if it has one, otherwise "". @@ -179,9 +190,11 @@ const StringRef root_name(StringRef path); /// @brief Get root directory. /// -/// /goo/hello => / -/// c:/hello => / -/// d/file.txt => <empty> +/// @code +/// /goo/hello => / +/// c:/hello => / +/// d/file.txt => <empty> +/// @endcode /// /// @param path Input path. /// @result The root directory of \a path if it has one, otherwise @@ -198,9 +211,11 @@ const StringRef root_path(StringRef path); /// @brief Get relative path. /// -/// C:\hello\world => hello\world -/// foo/bar => foo/bar -/// /foo/bar => foo/bar +/// @code +/// C:\hello\world => hello\world +/// foo/bar => foo/bar +/// /foo/bar => foo/bar +/// @endcode /// /// @param path Input path. /// @result The path starting after root_path if one exists, otherwise "". @@ -208,9 +223,11 @@ const StringRef relative_path(StringRef path); /// @brief Get parent path. /// -/// / => <empty> -/// /foo => / -/// foo/../bar => foo/.. +/// @code +/// / => <empty> +/// /foo => / +/// foo/../bar => foo/.. +/// @endcode /// /// @param path Input path. /// @result The parent path of \a path if one exists, otherwise "". @@ -218,10 +235,12 @@ const StringRef parent_path(StringRef path); /// @brief Get filename. /// -/// /foo.txt => foo.txt -/// . => . -/// .. => .. -/// / => / +/// @code +/// /foo.txt => foo.txt +/// . => . +/// .. => .. +/// / => / +/// @endcode /// /// @param path Input path. /// @result The filename part of \a path. This is defined as the last component @@ -234,11 +253,13 @@ const StringRef filename(StringRef path); /// substring of filename ending at (but not including) the last dot. Otherwise /// it is filename. /// -/// /foo/bar.txt => bar -/// /foo/bar => bar -/// /foo/.txt => <empty> -/// /foo/. => . -/// /foo/.. => .. +/// @code +/// /foo/bar.txt => bar +/// /foo/bar => bar +/// /foo/.txt => <empty> +/// /foo/. => . +/// /foo/.. => .. +/// @endcode /// /// @param path Input path. /// @result The stem of \a path. @@ -250,9 +271,11 @@ const StringRef stem(StringRef path); /// substring of filename starting at (and including) the last dot, and ending /// at the end of \a path. Otherwise "". /// -/// /foo/bar.txt => .txt -/// /foo/bar => <empty> -/// /foo/.txt => .txt +/// @code +/// /foo/bar.txt => .txt +/// /foo/bar => <empty> +/// /foo/.txt => .txt +/// @endcode /// /// @param path Input path. /// @result The extension of \a path. @@ -272,7 +295,7 @@ bool is_separator(char value); /// ignored if the user or system has set the typical environment variable /// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. /// -/// @param Result Holds the resulting path name. +/// @param result Holds the resulting path name. void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); /// @brief Has root name? diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h index 9b3ecda..2122e06 100644 --- a/include/llvm/Support/PrettyStackTrace.h +++ b/include/llvm/Support/PrettyStackTrace.h @@ -16,6 +16,8 @@ #ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H #define LLVM_SUPPORT_PRETTYSTACKTRACE_H +#include "llvm/Support/Compiler.h" + namespace llvm { class raw_ostream; @@ -32,8 +34,8 @@ namespace llvm { /// virtual stack trace. This gets dumped out if the program crashes. class PrettyStackTraceEntry { const PrettyStackTraceEntry *NextEntry; - PrettyStackTraceEntry(const PrettyStackTraceEntry &); // DO NOT IMPLEMENT - void operator=(const PrettyStackTraceEntry&); // DO NOT IMPLEMENT + PrettyStackTraceEntry(const PrettyStackTraceEntry &) LLVM_DELETED_FUNCTION; + void operator=(const PrettyStackTraceEntry&) LLVM_DELETED_FUNCTION; public: PrettyStackTraceEntry(); virtual ~PrettyStackTraceEntry(); @@ -52,7 +54,7 @@ namespace llvm { const char *Str; public: PrettyStackTraceString(const char *str) : Str(str) {} - virtual void print(raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const LLVM_OVERRIDE; }; /// PrettyStackTraceProgram - This object prints a specified program arguments @@ -63,7 +65,7 @@ namespace llvm { public: PrettyStackTraceProgram(int argc, const char * const*argv) : ArgC(argc), ArgV(argv) {} - virtual void print(raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const LLVM_OVERRIDE; }; } // end namespace llvm diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index a85f235..7c9a951 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -34,8 +34,8 @@ namespace sys { void *Data_; // Noncopyable. - Program(const Program& other); - Program& operator=(const Program& other); + Program(const Program& other) LLVM_DELETED_FUNCTION; + Program& operator=(const Program& other) LLVM_DELETED_FUNCTION; /// @name Methods /// @{ diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h index 0d4cb81..935b307 100644 --- a/include/llvm/Support/RWMutex.h +++ b/include/llvm/Support/RWMutex.h @@ -14,6 +14,7 @@ #ifndef LLVM_SYSTEM_RWMUTEX_H #define LLVM_SYSTEM_RWMUTEX_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/Threading.h" #include <cassert> @@ -75,8 +76,8 @@ namespace llvm /// @name Do Not Implement /// @{ private: - RWMutexImpl(const RWMutexImpl & original); - void operator=(const RWMutexImpl &); + RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION; + void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION; /// @} }; diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 7648e77..ffe09b1 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -36,7 +36,7 @@ namespace llvm { Newline=2 }; - /// Compiles the given POSIX Extended Regular Expression \arg Regex. + /// Compiles the given POSIX Extended Regular Expression \p Regex. /// This implementation supports regexes and matching strings with embedded /// NUL characters. Regex(StringRef Regex, unsigned Flags = NoFlags); @@ -51,17 +51,17 @@ namespace llvm { /// many entries plus one for the whole regex (as element 0). unsigned getNumMatches() const; - /// matches - Match the regex against a given \arg String. + /// matches - Match the regex against a given \p String. /// /// \param Matches - If given, on a successful match this will be filled in - /// with references to the matched group expressions (inside \arg String), + /// with references to the matched group expressions (inside \p String), /// the first group is always the entire pattern. /// /// This returns true on a successful match. bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = 0); /// sub - Return the result of replacing the first match of the regex in - /// \arg String with the \arg Repl string. Backreferences like "\0" in the + /// \p String with the \p Repl string. Backreferences like "\0" in the /// replacement string are replaced with the appropriate match substring. /// /// Note that the replacement string has backslash escaping performed on diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h index d0375be..29eafb6 100644 --- a/include/llvm/Support/Registry.h +++ b/include/llvm/Support/Registry.h @@ -37,7 +37,7 @@ namespace llvm { /// is necessary to define an alternate traits class. template <typename T> class RegistryTraits { - RegistryTraits(); // Do not implement. + RegistryTraits() LLVM_DELETED_FUNCTION; public: typedef SimpleRegistryEntry<T> entry; @@ -63,7 +63,7 @@ namespace llvm { class iterator; private: - Registry(); // Do not implement. + Registry() LLVM_DELETED_FUNCTION; static void Announce(const entry &E) { for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next) @@ -120,6 +120,7 @@ namespace llvm { /// Abstract base class for registry listeners, which are informed when new /// entries are added to the registry. Simply subclass and instantiate: /// + /// \code /// class CollectorPrinter : public Registry<Collector>::listener { /// protected: /// void registered(const Registry<Collector>::entry &e) { @@ -131,7 +132,7 @@ namespace llvm { /// }; /// /// CollectorPrinter Printer; - /// + /// \endcode class listener { listener *Prev, *Next; diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 8949a3a..bcf95f2 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -64,9 +64,9 @@ private: DiagHandlerTy DiagHandler; void *DiagContext; - - SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT - void operator=(const SourceMgr&); // DO NOT IMPLEMENT + + SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION; + void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION; public: SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {} ~SourceMgr(); @@ -145,7 +145,7 @@ public: /// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// - /// @param Type - If non-null, the kind of message (e.g., "error") which is + /// @param Msg If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const; diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h index 531dbb2..a2b4bcb 100644 --- a/include/llvm/Support/StreamableMemoryObject.h +++ b/include/llvm/Support/StreamableMemoryObject.h @@ -12,6 +12,7 @@ #define STREAMABLEMEMORYOBJECT_H_ #include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/DataStream.h" #include <vector> @@ -107,14 +108,15 @@ class StreamableMemoryObject : public MemoryObject { class StreamingMemoryObject : public StreamableMemoryObject { public: StreamingMemoryObject(DataStreamer *streamer); - virtual uint64_t getBase() const { return 0; } - virtual uint64_t getExtent() const; - virtual int readByte(uint64_t address, uint8_t* ptr) const; + virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; } + virtual uint64_t getExtent() const LLVM_OVERRIDE; + virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE; virtual int readBytes(uint64_t address, uint64_t size, uint8_t* buf, - uint64_t* copied) const ; - virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const { + uint64_t* copied) const LLVM_OVERRIDE; + virtual const uint8_t *getPointer(uint64_t address, + uint64_t size) const LLVM_OVERRIDE { // This could be fixed by ensuring the bytes are fetched and making a copy, // requiring that the bitcode size be known, or otherwise ensuring that // the memory doesn't go away/get reallocated, but it's @@ -122,8 +124,8 @@ public: assert(0 && "getPointer in streaming memory objects not allowed"); return NULL; } - virtual bool isValidAddress(uint64_t address) const; - virtual bool isObjectEnd(uint64_t address) const; + virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE; + virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE; /// Drop s bytes from the front of the stream, pushing the positions of the /// remaining bytes down by s. This is used to skip past the bitcode header, @@ -170,8 +172,8 @@ private: return true; } - StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT - void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT + StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; + void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; }; StreamableMemoryObject *getNonStreamedMemoryObject( diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index c65faa6..45f7816 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -26,11 +26,11 @@ namespace llvm { -class TargetData; +class DataLayout; /// TargetFolder - Create constants with target dependent folding. class TargetFolder { - const TargetData *TD; + const DataLayout *TD; /// Fold - Fold the constant using target specific information. Constant *Fold(Constant *C) const { @@ -41,7 +41,7 @@ class TargetFolder { } public: - explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {} + explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {} //===--------------------------------------------------------------------===// // Binary Operators @@ -177,7 +177,14 @@ public: return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); } Constant *CreatePointerCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getPointerCast(C, DestTy); + if (C->getType() == DestTy) + return C; // avoid calling Fold + return Fold(ConstantExpr::getPointerCast(C, DestTy)); + } + Constant *CreateFPCast(Constant *C, Type *DestTy) const { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return Fold(ConstantExpr::getFPCast(C, DestTy)); } Constant *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index c0be8f1..ca58bfb 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -93,7 +93,9 @@ namespace llvm { CodeGenOpt::Level OL); typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, MCStreamer &Streamer); - typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT); + typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, + StringRef TT, + StringRef CPU); typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T, const MCRegisterInfo &MRI, const MCAsmInfo &MAI); @@ -271,7 +273,7 @@ namespace llvm { /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified /// target triple. /// - /// \arg Triple - This argument is used to determine the target machine + /// \param Triple This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. @@ -317,12 +319,12 @@ namespace llvm { /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. /// - /// \arg Triple - This argument is used to determine the target machine + /// \param Triple This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. - /// \arg CPU - This specifies the name of the target CPU. - /// \arg Features - This specifies the string representation of the + /// \param CPU This specifies the name of the target CPU. + /// \param Features This specifies the string representation of the /// additional target features. MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU, StringRef Features) const { @@ -332,9 +334,9 @@ namespace llvm { } /// createTargetMachine - Create a target specific machine implementation - /// for the specified \arg Triple. + /// for the specified \p Triple. /// - /// \arg Triple - This argument is used to determine the target machine + /// \param Triple This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. @@ -351,12 +353,11 @@ namespace llvm { /// createMCAsmBackend - Create a target specific assembly parser. /// - /// \arg Triple - The target triple string. - /// \arg Backend - The target independent assembler object. - MCAsmBackend *createMCAsmBackend(StringRef Triple) const { + /// \param Triple The target triple string. + MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const { if (!MCAsmBackendCtorFn) return 0; - return MCAsmBackendCtorFn(*this, Triple); + return MCAsmBackendCtorFn(*this, Triple, CPU); } /// createMCAsmLexer - Create a target specific assembly lexer. @@ -370,7 +371,7 @@ namespace llvm { /// createMCAsmParser - Create a target specific assembly parser. /// - /// \arg Parser - The target independent parser implementation to use for + /// \param Parser The target independent parser implementation to use for /// parsing and lexing. MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser) const { @@ -416,13 +417,13 @@ namespace llvm { /// createMCObjectStreamer - Create a target specific MCStreamer. /// - /// \arg TT - The target triple. - /// \arg Ctx - The target context. - /// \arg TAB - The target assembler backend object. Takes ownership. - /// \arg _OS - The stream object. - /// \arg _Emitter - The target independent assembler object.Takes ownership. - /// \arg RelaxAll - Relax all fixups? - /// \arg NoExecStack - Mark file as not needing a executable stack. + /// \param TT The target triple. + /// \param Ctx The target context. + /// \param TAB The target assembler backend object. Takes ownership. + /// \param _OS The stream object. + /// \param _Emitter The target independent assembler object.Takes ownership. + /// \param RelaxAll Relax all fixups? + /// \param NoExecStack Mark file as not needing a executable stack. MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &_OS, @@ -1063,8 +1064,9 @@ namespace llvm { } private: - static MCAsmBackend *Allocator(const Target &T, StringRef Triple) { - return new MCAsmBackendImpl(T, Triple); + static MCAsmBackend *Allocator(const Target &T, StringRef Triple, + StringRef CPU) { + return new MCAsmBackendImpl(T, Triple, CPU); } }; diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h index c0e842c..9017afb 100644 --- a/include/llvm/Support/Threading.h +++ b/include/llvm/Support/Threading.h @@ -41,8 +41,8 @@ namespace llvm { /// before llvm_start_multithreaded(). void llvm_release_global_lock(); - /// llvm_execute_on_thread - Execute the given \arg UserFn on a separate - /// thread, passing it the provided \arg UserData. + /// llvm_execute_on_thread - Execute the given \p UserFn on a separate + /// thread, passing it the provided \p UserData. /// /// This function does not guarantee that the code will actually be executed /// on a separate thread or honoring the requested stack size, but tries to do diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h index 94f132a..e780b50 100644 --- a/include/llvm/Support/TimeValue.h +++ b/include/llvm/Support/TimeValue.h @@ -153,7 +153,6 @@ namespace sys { /// Determine if \p this is greater than or equal to \p that. /// @returns True iff *this >= that. - /// @brief True if this >= that. int operator >= (const TimeValue &that) const { if ( this->seconds_ > that.seconds_ ) { return 1; @@ -164,8 +163,7 @@ namespace sys { } /// Determines if two TimeValue objects represent the same moment in time. - /// @brief True iff *this == that. - /// @brief True if this == that. + /// @returns True iff *this == that. int operator == (const TimeValue &that) const { return (this->seconds_ == that.seconds_) && (this->nanos_ == that.nanos_); @@ -173,8 +171,7 @@ namespace sys { /// Determines if two TimeValue objects represent times that are not the /// same. - /// @return True iff *this != that. - /// @brief True if this != that. + /// @returns True iff *this != that. int operator != (const TimeValue &that) const { return !(*this == that); } /// Adds two TimeValue objects together. diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 404cb6d..a741882 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_TIMER_H #define LLVM_SUPPORT_TIMER_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include "llvm/ADT/StringRef.h" #include <cassert> @@ -130,7 +131,7 @@ private: /// class TimeRegion { Timer *T; - TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT + TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION; public: explicit TimeRegion(Timer &t) : T(&t) { T->startTimer(); @@ -168,8 +169,8 @@ class TimerGroup { std::vector<std::pair<TimeRecord, std::string> > TimersToPrint; TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's. - TimerGroup(const TimerGroup &TG); // DO NOT IMPLEMENT - void operator=(const TimerGroup &TG); // DO NOT IMPLEMENT + TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION; + void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION; public: explicit TimerGroup(StringRef name); ~TimerGroup(); diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index 61e21b8..dbcf0fd 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -59,8 +59,8 @@ private: // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this // access. PointerIntPair<Value*, 2> VP; - - explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT. + + ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION; public: explicit ValueHandleBase(HandleBaseKind Kind) : PrevPair(0, Kind), Next(0), VP(0, 0) {} diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index 98910eb..12958fa 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -133,7 +133,6 @@ public: virtual void skip() {} unsigned int getType() const { return TypeID; } - static inline bool classof(const Node *) { return true; } void *operator new ( size_t Size , BumpPtrAllocator &Alloc @@ -166,7 +165,6 @@ class NullNode : public Node { public: NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {} - static inline bool classof(const NullNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Null; } @@ -199,7 +197,6 @@ public: /// This happens with escaped characters and multi-line literals. StringRef getValue(SmallVectorImpl<char> &Storage) const; - static inline bool classof(const ScalarNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Scalar; } @@ -241,12 +238,11 @@ public: /// @returns The value, or nullptr if failed() == true. Node *getValue(); - virtual void skip() { + virtual void skip() LLVM_OVERRIDE { getKey()->skip(); getValue()->skip(); } - static inline bool classof(const KeyValueNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_KeyValue; } @@ -358,11 +354,10 @@ public: iterator end() { return iterator(); } - virtual void skip() { + virtual void skip() LLVM_OVERRIDE { yaml::skip(*this); } - static inline bool classof(const MappingNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Mapping; } @@ -421,11 +416,10 @@ public: iterator end() { return iterator(); } - virtual void skip() { + virtual void skip() LLVM_OVERRIDE { yaml::skip(*this); } - static inline bool classof(const SequenceNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Sequence; } @@ -450,7 +444,6 @@ public: StringRef getName() const { return Name; } Node *getTarget(); - static inline bool classof(const ScalarNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Alias; } diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h index 2b3c329..2823af3 100644 --- a/include/llvm/Support/circular_raw_ostream.h +++ b/include/llvm/Support/circular_raw_ostream.h @@ -81,12 +81,12 @@ namespace llvm Filled = false; } - virtual void write_impl(const char *Ptr, size_t Size); + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, /// not counting the bytes currently in the buffer. /// - virtual uint64_t current_pos() const { + virtual uint64_t current_pos() const LLVM_OVERRIDE { // This has the same effect as calling TheStream.current_pos(), // but that interface is private. return TheStream->tell() - TheStream->GetNumBytesInBuffer(); diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h index 4f5d361..4385721 100644 --- a/include/llvm/Support/raw_os_ostream.h +++ b/include/llvm/Support/raw_os_ostream.h @@ -24,14 +24,14 @@ namespace llvm { /// use the underlying stream to detect errors. class raw_os_ostream : public raw_ostream { std::ostream &OS; - + /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size); - + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const; - + virtual uint64_t current_pos() const LLVM_OVERRIDE; + public: raw_os_ostream(std::ostream &O) : OS(O) {} ~raw_os_ostream(); diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 5de749a..eab0f2d 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_RAW_OSTREAM_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -29,8 +30,8 @@ namespace llvm { class raw_ostream { private: // Do not implement. raw_ostream is noncopyable. - void operator=(const raw_ostream &); - raw_ostream(const raw_ostream &); + void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION; + raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION; /// The buffer is handled in such a way that the buffer is /// uninitialized, unbuffered, or out of space when OutBufCur >= @@ -191,10 +192,10 @@ public: raw_ostream &operator<<(double N); - /// write_hex - Output \arg N in hexadecimal, without any prefix or padding. + /// write_hex - Output \p N in hexadecimal, without any prefix or padding. raw_ostream &write_hex(unsigned long long N); - /// write_escaped - Output \arg Str, turning '\\', '\t', '\n', '"', and + /// write_escaped - Output \p Str, turning '\\', '\t', '\n', '"', and /// anything that doesn't satisfy std::isprint into an escape sequence. raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false); @@ -210,13 +211,19 @@ public: /// Changes the foreground color of text that will be output from this point /// forward. - /// @param colors ANSI color to use, the special SAVEDCOLOR can be used to + /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to /// change only the bold attribute, and keep colors untouched - /// @param bold bold/brighter text, default false - /// @param bg if true change the background, default: change foreground + /// @param Bold bold/brighter text, default false + /// @param BG if true change the background, default: change foreground /// @returns itself so it can be used within << invocations - virtual raw_ostream &changeColor(enum Colors, bool = false, bool = false) { - return *this; } + virtual raw_ostream &changeColor(enum Colors Color, + bool Bold = false, + bool BG = false) { + (void)Color; + (void)Bold; + (void)BG; + return *this; + } /// Resets the colors to terminal defaults. Call this when you are done /// outputting colored text, or before program exit. @@ -239,15 +246,16 @@ public: private: /// write_impl - The is the piece of the class that is implemented - /// by subclasses. This writes the \args Size bytes starting at - /// \arg Ptr to the underlying stream. + /// by subclasses. This writes the \p Size bytes starting at + /// \p Ptr to the underlying stream. /// /// This function is guaranteed to only be called at a point at which it is /// safe for the subclass to install a new buffer via SetBuffer. /// - /// \arg Ptr - The start of the data to be written. For buffered streams this + /// \param Ptr The start of the data to be written. For buffered streams this /// is guaranteed to be the start of the buffer. - /// \arg Size - The number of bytes to be written. + /// + /// \param Size The number of bytes to be written. /// /// \invariant { Size > 0 } virtual void write_impl(const char *Ptr, size_t Size) = 0; @@ -314,14 +322,14 @@ class raw_fd_ostream : public raw_ostream { uint64_t pos; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size); + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const { return pos; } + virtual uint64_t current_pos() const LLVM_OVERRIDE { return pos; } /// preferred_buffer_size - Determine an efficient buffer size. - virtual size_t preferred_buffer_size() const; + virtual size_t preferred_buffer_size() const LLVM_OVERRIDE; /// error_detected - Set the flag indicating that an output error has /// been encountered. @@ -382,14 +390,14 @@ public: } virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, - bool bg=false); - virtual raw_ostream &resetColor(); + bool bg=false) LLVM_OVERRIDE; + virtual raw_ostream &resetColor() LLVM_OVERRIDE; - virtual raw_ostream &reverseColor(); + virtual raw_ostream &reverseColor() LLVM_OVERRIDE; - virtual bool is_displayed() const; + virtual bool is_displayed() const LLVM_OVERRIDE; - virtual bool has_colors() const; + virtual bool has_colors() const LLVM_OVERRIDE; /// has_error - Return the value of the flag in this raw_fd_ostream indicating /// whether an output error has been encountered. @@ -435,11 +443,11 @@ class raw_string_ostream : public raw_ostream { std::string &OS; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size); + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const { return OS.size(); } + virtual uint64_t current_pos() const LLVM_OVERRIDE { return OS.size(); } public: explicit raw_string_ostream(std::string &O) : OS(O) {} ~raw_string_ostream(); @@ -459,15 +467,15 @@ class raw_svector_ostream : public raw_ostream { SmallVectorImpl<char> &OS; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size); + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const; + virtual uint64_t current_pos() const LLVM_OVERRIDE; public: /// Construct a new raw_svector_ostream. /// - /// \arg O - The vector to write to; this should generally have at least 128 + /// \param O The vector to write to; this should generally have at least 128 /// bytes free to avoid any extraneous memory overhead. explicit raw_svector_ostream(SmallVectorImpl<char> &O); ~raw_svector_ostream(); @@ -485,11 +493,11 @@ public: /// raw_null_ostream - A raw_ostream that discards all output. class raw_null_ostream : public raw_ostream { /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t size); + virtual void write_impl(const char *Ptr, size_t size) LLVM_OVERRIDE; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const; + virtual uint64_t current_pos() const LLVM_OVERRIDE; public: explicit raw_null_ostream() {} diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h index af81206..0d164f6 100644 --- a/include/llvm/Support/system_error.h +++ b/include/llvm/Support/system_error.h @@ -17,6 +17,8 @@ #ifndef LLVM_SYSTEM_SYSTEM_ERROR_H #define LLVM_SYSTEM_SYSTEM_ERROR_H +#include "llvm/Support/Compiler.h" + /* system_error synopsis @@ -629,8 +631,8 @@ public: private: error_category(); - error_category(const error_category&);// = delete; - error_category& operator=(const error_category&);// = delete; + error_category(const error_category&) LLVM_DELETED_FUNCTION; + error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION; public: virtual const char* name() const = 0; @@ -651,7 +653,7 @@ public: class _do_message : public error_category { public: - virtual std::string message(int ev) const; + virtual std::string message(int ev) const LLVM_OVERRIDE; }; const error_category& generic_category(); diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 7b97547..f930639 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -54,8 +54,9 @@ struct is_class // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For // more details: // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 - public: - enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) }; +public: + static const bool value = + sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)); }; @@ -162,12 +163,11 @@ template <typename T> class is_integral_or_enum { static UnderlyingT &nonce_instance; public: - enum { + static const bool value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && !is_same<UnderlyingT, float>::value && !is_same<UnderlyingT, double>::value && - sizeof(char) != sizeof(check_int_convertible(nonce_instance))) - }; + sizeof(char) != sizeof(check_int_convertible(nonce_instance))); }; // enable_if_c - Enable/disable a template based on a metafunction diff --git a/include/llvm/SymbolTableListTraits.h b/include/llvm/SymbolTableListTraits.h index 91a4eb9..ec5c88f 100644 --- a/include/llvm/SymbolTableListTraits.h +++ b/include/llvm/SymbolTableListTraits.h @@ -46,7 +46,6 @@ public: /// getListOwner - Return the object that owns this list. If this is a list /// of instructions, it returns the BasicBlock that owns them. ItemParentClass *getListOwner() { - typedef iplist<ValueSubClass> ItemParentClass::*Sublist; size_t Offset(size_t(&((ItemParentClass*)0->*ItemParentClass:: getSublistAccess(static_cast<ValueSubClass*>(0))))); iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this)); diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h index fd5f805..2f6b7e6 100644 --- a/include/llvm/TableGen/Error.h +++ b/include/llvm/TableGen/Error.h @@ -19,26 +19,17 @@ namespace llvm { -class TGError { - SMLoc Loc; - std::string Message; -public: - TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {} - - SMLoc getLoc() const { return Loc; } - const std::string &getMessage() const { return Message; } -}; - -void PrintWarning(SMLoc WarningLoc, const Twine &Msg); +void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg); void PrintWarning(const char *Loc, const Twine &Msg); void PrintWarning(const Twine &Msg); -void PrintWarning(const TGError &Warning); -void PrintError(SMLoc ErrorLoc, const Twine &Msg); +void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg); void PrintError(const char *Loc, const Twine &Msg); void PrintError(const Twine &Msg); -void PrintError(const TGError &Error); +LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const std::string &Msg); +LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, + const std::string &Msg); extern SourceMgr SrcMgr; diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h index deaef4a..6b51e20 100644 --- a/include/llvm/TableGen/Main.h +++ b/include/llvm/TableGen/Main.h @@ -16,10 +16,13 @@ namespace llvm { -class TableGenAction; +class RecordKeeper; +class raw_ostream; +/// \brief Perform the action using Records, and write output to OS. +/// \returns true on error, false otherwise +typedef bool TableGenMainFn(raw_ostream &OS, RecordKeeper &Records); -/// Run the table generator, performing the specified Action on parsed records. -int TableGenMain(char *argv0, TableGenAction &Action); +int TableGenMain(char *argv0, TableGenMainFn *MainFn); } diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index a8256b7..319298c 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -66,10 +67,27 @@ class RecordKeeper; //===----------------------------------------------------------------------===// class RecTy { +public: + /// \brief Subclass discriminator (for dyn_cast<> et al.) + enum RecTyKind { + BitRecTyKind, + BitsRecTyKind, + IntRecTyKind, + StringRecTyKind, + ListRecTyKind, + DagRecTyKind, + RecordRecTyKind + }; + +private: + RecTyKind Kind; ListRecTy *ListTy; virtual void anchor(); + public: - RecTy() : ListTy(0) {} + RecTyKind getRecTyKind() const { return Kind; } + + RecTy(RecTyKind K) : Kind(K), ListTy(0) {} virtual ~RecTy() {} virtual std::string getAsString() const = 0; @@ -132,8 +150,12 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { /// class BitRecTy : public RecTy { static BitRecTy Shared; - BitRecTy() {} + BitRecTy() : RecTy(BitRecTyKind) {} public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == BitRecTyKind; + } + static BitRecTy *get() { return &Shared; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -152,9 +174,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const { return "bit"; } + virtual std::string getAsString() const { return "bit"; } - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } @@ -173,8 +195,12 @@ public: /// class BitsRecTy : public RecTy { unsigned Size; - explicit BitsRecTy(unsigned Sz) : Size(Sz) {} + explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == BitsRecTyKind; + } + static BitsRecTy *get(unsigned Sz); unsigned getNumBits() const { return Size; } @@ -195,9 +221,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const; + virtual std::string getAsString() const; - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; } @@ -217,8 +243,12 @@ public: /// class IntRecTy : public RecTy { static IntRecTy Shared; - IntRecTy() {} + IntRecTy() : RecTy(IntRecTyKind) {} public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == IntRecTyKind; + } + static IntRecTy *get() { return &Shared; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -237,9 +267,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const { return "int"; } + virtual std::string getAsString() const { return "int"; } - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } @@ -257,8 +287,12 @@ public: /// class StringRecTy : public RecTy { static StringRecTy Shared; - StringRecTy() {} + StringRecTy() : RecTy(StringRecTyKind) {} public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == StringRecTyKind; + } + static StringRecTy *get() { return &Shared; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -278,9 +312,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const { return "string"; } + virtual std::string getAsString() const { return "string"; } - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } @@ -300,9 +334,13 @@ public: /// class ListRecTy : public RecTy { RecTy *Ty; - explicit ListRecTy(RecTy *T) : Ty(T) {} + explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} friend ListRecTy *RecTy::getListTy(); public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == ListRecTyKind; + } + static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } @@ -322,9 +360,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const; + virtual std::string getAsString() const; - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } @@ -343,8 +381,12 @@ public: /// class DagRecTy : public RecTy { static DagRecTy Shared; - DagRecTy() {} + DagRecTy() : RecTy(DagRecTyKind) {} public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == DagRecTyKind; + } + static DagRecTy *get() { return &Shared; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -363,9 +405,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const { return "dag"; } + virtual std::string getAsString() const { return "dag"; } - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } @@ -384,9 +426,13 @@ public: /// class RecordRecTy : public RecTy { Record *Rec; - explicit RecordRecTy(Record *R) : Rec(R) {} + explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {} friend class Record; public: + static bool classof(const RecTy *RT) { + return RT->getRecTyKind() == RecordRecTyKind; + } + static RecordRecTy *get(Record *R); Record *getRecord() const { return Rec; } @@ -407,9 +453,9 @@ public: virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} - std::string getAsString() const; + virtual std::string getAsString() const; - bool typeIsConvertibleTo(const RecTy *RHS) const { + virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } @@ -431,12 +477,53 @@ RecTy *resolveTypes(RecTy *T1, RecTy *T2); //===----------------------------------------------------------------------===// class Init { - Init(const Init &); // Do not define. - Init &operator=(const Init &); // Do not define. +protected: + /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.) + /// + /// This enum is laid out by a preorder traversal of the inheritance + /// hierarchy, and does not contain an entry for abstract classes, as per + /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst. + /// + /// We also explicitly include "first" and "last" values for each + /// interior node of the inheritance tree, to make it easier to read the + /// corresponding classof(). + /// + /// We could pack these a bit tighter by not having the IK_FirstXXXInit + /// and IK_LastXXXInit be their own values, but that would degrade + /// readability for really no benefit. + enum InitKind { + IK_BitInit, + IK_BitsInit, + IK_FirstTypedInit, + IK_DagInit, + IK_DefInit, + IK_FieldInit, + IK_IntInit, + IK_ListInit, + IK_FirstOpInit, + IK_BinOpInit, + IK_TernOpInit, + IK_UnOpInit, + IK_LastOpInit, + IK_StringInit, + IK_VarInit, + IK_VarListElementInit, + IK_LastTypedInit, + IK_UnsetInit, + IK_VarBitInit + }; + +private: + const InitKind Kind; + Init(const Init &) LLVM_DELETED_FUNCTION; + Init &operator=(const Init &) LLVM_DELETED_FUNCTION; virtual void anchor(); +public: + InitKind getKind() const { return Kind; } + protected: - Init(void) {} + explicit Init(InitKind K) : Kind(K) {} public: virtual ~Init() {} @@ -509,6 +596,18 @@ public: virtual Init *resolveReferences(Record &R, const RecordVal *RV) const { return const_cast<Init *>(this); } + + /// getBit - This method is used to return the initializer for the specified + /// bit. + virtual Init *getBit(unsigned Bit) const = 0; + + /// getBitVar - This method is used to retrieve the initializer for bit + /// reference. For non-VarBitInit, it simply returns itself. + virtual Init *getBitVar() const { return const_cast<Init*>(this); } + + /// getBitNum - This method is used to retrieve the bit number of a bit + /// reference. For non-VarBitInit, it simply returns 0. + virtual unsigned getBitNum() const { return 0; } }; inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { @@ -521,13 +620,17 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { class TypedInit : public Init { RecTy *Ty; - TypedInit(const TypedInit &Other); // Do not define. - TypedInit &operator=(const TypedInit &Other); // Do not define. + TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION; + TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION; protected: - explicit TypedInit(RecTy *T) : Ty(T) {} + explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {} public: + static bool classof(const Init *I) { + return I->getKind() >= IK_FirstTypedInit && + I->getKind() <= IK_LastTypedInit; + } RecTy *getType() const { return Ty; } virtual Init * @@ -541,13 +644,6 @@ public: /// virtual RecTy *getFieldType(const std::string &FieldName) const; - /// resolveBitReference - This method is used to implement - /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return null. - /// - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const = 0; - /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. @@ -559,18 +655,25 @@ public: /// UnsetInit - ? - Represents an uninitialized value /// class UnsetInit : public Init { - UnsetInit() : Init() {} - UnsetInit(const UnsetInit &); // Do not define. - UnsetInit &operator=(const UnsetInit &Other); // Do not define. + UnsetInit() : Init(IK_UnsetInit) {} + UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION; + UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_UnsetInit; + } static UnsetInit *get(); virtual Init *convertInitializerTo(RecTy *Ty) const { return Ty->convertValue(const_cast<UnsetInit *>(this)); } + virtual Init *getBit(unsigned Bit) const { + return const_cast<UnsetInit*>(this); + } + virtual bool isComplete() const { return false; } virtual std::string getAsString() const { return "?"; } }; @@ -581,12 +684,15 @@ public: class BitInit : public Init { bool Value; - explicit BitInit(bool V) : Value(V) {} - BitInit(const BitInit &Other); // Do not define. - BitInit &operator=(BitInit &Other); // Do not define. + explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} + BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION; + BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_BitInit; + } static BitInit *get(bool V); bool getValue() const { return Value; } @@ -595,6 +701,11 @@ public: return Ty->convertValue(const_cast<BitInit *>(this)); } + virtual Init *getBit(unsigned Bit) const { + assert(Bit < 1 && "Bit index out of range!"); + return const_cast<BitInit*>(this); + } + virtual std::string getAsString() const { return Value ? "1" : "0"; } }; @@ -604,23 +715,22 @@ public: class BitsInit : public Init, public FoldingSetNode { std::vector<Init*> Bits; - BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {} + BitsInit(ArrayRef<Init *> Range) + : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {} - BitsInit(const BitsInit &Other); // Do not define. - BitsInit &operator=(const BitsInit &Other); // Do not define. + BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION; + BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_BitsInit; + } static BitsInit *get(ArrayRef<Init *> Range); void Profile(FoldingSetNodeID &ID) const; unsigned getNumBits() const { return Bits.size(); } - Init *getBit(unsigned Bit) const { - assert(Bit < Bits.size() && "Bit index out of range!"); - return Bits[Bit]; - } - virtual Init *convertInitializerTo(RecTy *Ty) const { return Ty->convertValue(const_cast<BitsInit *>(this)); } @@ -640,6 +750,11 @@ public: virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; + + virtual Init *getBit(unsigned Bit) const { + assert(Bit < Bits.size() && "Bit index out of range!"); + return Bits[Bit]; + } }; @@ -648,12 +763,16 @@ public: class IntInit : public TypedInit { int64_t Value; - explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {} + explicit IntInit(int64_t V) + : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {} - IntInit(const IntInit &Other); // Do not define. - IntInit &operator=(const IntInit &Other); // Do note define. + IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION; + IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_IntInit; + } static IntInit *get(int64_t V); int64_t getValue() const { return Value; } @@ -666,15 +785,6 @@ public: virtual std::string getAsString() const; - /// resolveBitReference - This method is used to implement - /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return null. - /// - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const { - llvm_unreachable("Illegal bit reference off int"); - } - /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. @@ -682,6 +792,10 @@ public: unsigned Elt) const { llvm_unreachable("Illegal element reference off int"); } + + virtual Init *getBit(unsigned Bit) const { + return BitInit::get((Value & (1ULL << Bit)) != 0); + } }; @@ -691,13 +805,16 @@ class StringInit : public TypedInit { std::string Value; explicit StringInit(const std::string &V) - : TypedInit(StringRecTy::get()), Value(V) {} + : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} - StringInit(const StringInit &Other); // Do not define. - StringInit &operator=(const StringInit &Other); // Do not define. + StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION; + StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_StringInit; + } static StringInit *get(StringRef); const std::string &getValue() const { return Value; } @@ -709,15 +826,6 @@ public: virtual std::string getAsString() const { return "\"" + Value + "\""; } virtual std::string getAsUnquotedString() const { return Value; } - /// resolveBitReference - This method is used to implement - /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return null. - /// - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const { - llvm_unreachable("Illegal bit reference off string"); - } - /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. @@ -725,6 +833,10 @@ public: unsigned Elt) const { llvm_unreachable("Illegal element reference off string"); } + + virtual Init *getBit(unsigned Bit) const { + llvm_unreachable("Illegal bit reference off string"); + } }; /// ListInit - [AL, AH, CL] - Represent a list of defs @@ -736,12 +848,16 @@ public: private: explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy) - : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {} + : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), + Values(Range.begin(), Range.end()) {} - ListInit(const ListInit &Other); // Do not define. - ListInit &operator=(const ListInit &Other); // Do not define. + ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION; + ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_ListInit; + } static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy); void Profile(FoldingSetNodeID &ID) const; @@ -754,7 +870,8 @@ public: Record *getElementAsRecord(unsigned i) const; - Init *convertInitListSlice(const std::vector<unsigned> &Elements) const; + virtual Init * + convertInitListSlice(const std::vector<unsigned> &Elements) const; virtual Init *convertInitializerTo(RecTy *Ty) const { return Ty->convertValue(const_cast<ListInit *>(this)); @@ -777,33 +894,32 @@ public: inline size_t size () const { return Values.size(); } inline bool empty() const { return Values.empty(); } - /// resolveBitReference - This method is used to implement - /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return null. - /// - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const { - llvm_unreachable("Illegal bit reference off list"); - } - /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const; + + virtual Init *getBit(unsigned Bit) const { + llvm_unreachable("Illegal bit reference off list"); + } }; /// OpInit - Base class for operators /// class OpInit : public TypedInit { - OpInit(const OpInit &Other); // Do not define. - OpInit &operator=(OpInit &Other); // Do not define. + OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION; + OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION; protected: - explicit OpInit(RecTy *Type) : TypedInit(Type) {} + explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {} public: + static bool classof(const Init *I) { + return I->getKind() >= IK_FirstOpInit && + I->getKind() <= IK_LastOpInit; + } // Clone - Clone this operator, replacing arguments with the new list virtual OpInit *clone(std::vector<Init *> &Operands) const = 0; @@ -818,10 +934,10 @@ public: return Ty->convertValue(const_cast<OpInit *>(this)); } - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const; virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const; + + virtual Init *getBit(unsigned Bit) const; }; @@ -835,12 +951,15 @@ private: Init *LHS; UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) - : OpInit(Type), Opc(opc), LHS(lhs) {} + : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {} - UnOpInit(const UnOpInit &Other); // Do not define. - UnOpInit &operator=(const UnOpInit &Other); // Do not define. + UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION; + UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_UnOpInit; + } static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); // Clone - Clone this operator, replacing arguments with the new list @@ -850,8 +969,8 @@ public: return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); } - int getNumOperands() const { return 1; } - Init *getOperand(int i) const { + virtual int getNumOperands() const { return 1; } + virtual Init *getOperand(int i) const { assert(i == 0 && "Invalid operand id for unary operator"); return getOperand(); } @@ -861,7 +980,7 @@ public: // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; + virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; @@ -878,12 +997,15 @@ private: Init *LHS, *RHS; BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {} + OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {} - BinOpInit(const BinOpInit &Other); // Do not define. - BinOpInit &operator=(const BinOpInit &Other); // Do not define. + BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION; + BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_BinOpInit; + } static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type); @@ -894,8 +1016,8 @@ public: return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); } - int getNumOperands() const { return 2; } - Init *getOperand(int i) const { + virtual int getNumOperands() const { return 2; } + virtual Init *getOperand(int i) const { assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); if (i == 0) { return getLHS(); @@ -910,7 +1032,7 @@ public: // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; + virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; @@ -928,12 +1050,15 @@ private: TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} + OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} - TernOpInit(const TernOpInit &Other); // Do not define. - TernOpInit &operator=(const TernOpInit &Other); // Do not define. + TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION; + TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_TernOpInit; + } static TernOpInit *get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type); @@ -946,8 +1071,8 @@ public: getType()); } - int getNumOperands() const { return 3; } - Init *getOperand(int i) const { + virtual int getNumOperands() const { return 3; } + virtual Init *getOperand(int i) const { assert((i == 0 || i == 1 || i == 2) && "Invalid operand id for ternary operator"); if (i == 0) { @@ -966,7 +1091,7 @@ public: // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; + virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; virtual bool isComplete() const { return false; } @@ -982,14 +1107,17 @@ class VarInit : public TypedInit { Init *VarName; explicit VarInit(const std::string &VN, RecTy *T) - : TypedInit(T), VarName(StringInit::get(VN)) {} + : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {} explicit VarInit(Init *VN, RecTy *T) - : TypedInit(T), VarName(VN) {} + : TypedInit(IK_VarInit, T), VarName(VN) {} - VarInit(const VarInit &Other); // Do not define. - VarInit &operator=(const VarInit &Other); // Do not define. + VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION; + VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarInit; + } static VarInit *get(const std::string &VN, RecTy *T); static VarInit *get(Init *VN, RecTy *T); @@ -1003,8 +1131,6 @@ public: return getNameInit()->getAsUnquotedString(); } - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const; virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const; @@ -1019,6 +1145,8 @@ public: /// virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; + virtual Init *getBit(unsigned Bit) const; + virtual std::string getAsString() const { return getName(); } }; @@ -1029,27 +1157,37 @@ class VarBitInit : public Init { TypedInit *TI; unsigned Bit; - VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) { - assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) && - ((BitsRecTy*)T->getType())->getNumBits() > B && + VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) { + assert(T->getType() && + (isa<IntRecTy>(T->getType()) || + (isa<BitsRecTy>(T->getType()) && + cast<BitsRecTy>(T->getType())->getNumBits() > B)) && "Illegal VarBitInit expression!"); } - VarBitInit(const VarBitInit &Other); // Do not define. - VarBitInit &operator=(const VarBitInit &Other); // Do not define. + VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION; + VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarBitInit; + } static VarBitInit *get(TypedInit *T, unsigned B); virtual Init *convertInitializerTo(RecTy *Ty) const { return Ty->convertValue(const_cast<VarBitInit *>(this)); } - TypedInit *getVariable() const { return TI; } - unsigned getBitNum() const { return Bit; } + virtual Init *getBitVar() const { return TI; } + virtual unsigned getBitNum() const { return Bit; } virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; + + virtual Init *getBit(unsigned B) const { + assert(B < 1 && "Bit index out of range!"); + return const_cast<VarBitInit*>(this); + } }; /// VarListElementInit - List[4] - Represent access to one element of a var or @@ -1059,18 +1197,20 @@ class VarListElementInit : public TypedInit { unsigned Element; VarListElementInit(TypedInit *T, unsigned E) - : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()), - TI(T), Element(E) { - assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) && + : TypedInit(IK_VarListElementInit, + cast<ListRecTy>(T->getType())->getElementType()), + TI(T), Element(E) { + assert(T->getType() && isa<ListRecTy>(T->getType()) && "Illegal VarBitInit expression!"); } - VarListElementInit(const VarListElementInit &Other); // Do not define. - VarListElementInit &operator=(const VarListElementInit &Other); // Do - // not - // define. + VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION; + void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarListElementInit; + } static VarListElementInit *get(TypedInit *T, unsigned E); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -1080,9 +1220,6 @@ public: TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const; - /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. @@ -1092,6 +1229,8 @@ public: virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; + + virtual Init *getBit(unsigned Bit) const; }; /// DefInit - AL - Represent a reference to a 'def' in the description @@ -1099,13 +1238,16 @@ public: class DefInit : public TypedInit { Record *Def; - DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {} + DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {} friend class Record; - DefInit(const DefInit &Other); // Do not define. - DefInit &operator=(const DefInit &Other); // Do not define. + DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION; + DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_DefInit; + } static DefInit *get(Record*); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -1122,12 +1264,7 @@ public: virtual std::string getAsString() const; - /// resolveBitReference - This method is used to implement - /// VarBitInit::resolveReferences. If the bit is able to be resolved, we - /// simply return the resolved value, otherwise we return null. - /// - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const { + virtual Init *getBit(unsigned Bit) const { llvm_unreachable("Illegal bit reference off def"); } @@ -1148,14 +1285,17 @@ class FieldInit : public TypedInit { std::string FieldName; // Field we are accessing FieldInit(Init *R, const std::string &FN) - : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { + : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) { assert(getType() && "FieldInit with non-record type!"); } - FieldInit(const FieldInit &Other); // Do not define. - FieldInit &operator=(const FieldInit &Other); // Do not define. + FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION; + FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_FieldInit; + } static FieldInit *get(Init *R, const std::string &FN); static FieldInit *get(Init *R, const Init *FN); @@ -1163,8 +1303,8 @@ public: return Ty->convertValue(const_cast<FieldInit *>(this)); } - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const; + virtual Init *getBit(unsigned Bit) const; + virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const; @@ -1189,14 +1329,17 @@ class DagInit : public TypedInit, public FoldingSetNode { DagInit(Init *V, const std::string &VN, ArrayRef<Init *> ArgRange, ArrayRef<std::string> NameRange) - : TypedInit(DagRecTy::get()), Val(V), ValName(VN), + : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN), Args(ArgRange.begin(), ArgRange.end()), ArgNames(NameRange.begin(), NameRange.end()) {} - DagInit(const DagInit &Other); // Do not define. - DagInit &operator=(const DagInit &Other); // Do not define. + DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION; + DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_DagInit; + } static DagInit *get(Init *V, const std::string &VN, ArrayRef<Init *> ArgRange, ArrayRef<std::string> NameRange); @@ -1243,8 +1386,7 @@ public: inline size_t name_size () const { return ArgNames.size(); } inline bool name_empty() const { return ArgNames.empty(); } - virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) const { + virtual Init *getBit(unsigned Bit) const { llvm_unreachable("Illegal bit reference off dag"); } @@ -1301,7 +1443,9 @@ class Record { // Unique record ID. unsigned ID; Init *Name; - SMLoc Loc; + // Location where record was instantiated, followed by the location of + // multiclass prototypes used. + SmallVector<SMLoc, 4> Locs; std::vector<Init *> TemplateArgs; std::vector<RecordVal> Values; std::vector<Record*> SuperClasses; @@ -1317,15 +1461,25 @@ class Record { public: // Constructs a record. - explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) : - ID(LastID++), Name(StringInit::get(N)), Loc(loc), TrackedRecords(records), - TheInit(0) { + explicit Record(const std::string &N, ArrayRef<SMLoc> locs, + RecordKeeper &records) : + ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), + TrackedRecords(records), TheInit(0) { init(); } - explicit Record(Init *N, SMLoc loc, RecordKeeper &records) : - ID(LastID++), Name(N), Loc(loc), TrackedRecords(records), TheInit(0) { + explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records) : + ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), + TrackedRecords(records), TheInit(0) { init(); } + + // When copy-constructing a Record, we must still guarantee a globally unique + // ID number. All other fields can be copied normally. + Record(const Record &O) : + ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), + Values(O.Values), SuperClasses(O.SuperClasses), + TrackedRecords(O.TrackedRecords), TheInit(O.TheInit) { } + ~Record() {} @@ -1345,7 +1499,7 @@ public: void setName(Init *Name); // Also updates RecordKeeper. void setName(const std::string &Name); // Also updates RecordKeeper. - SMLoc getLoc() const { return Loc; } + ArrayRef<SMLoc> getLoc() const { return Locs; } /// get the corresponding DefInit. DefInit *getDefInit(); @@ -1507,6 +1661,12 @@ public: /// bool getValueAsBit(StringRef FieldName) const; + /// getValueAsBitOrUnset - This method looks up the specified field and + /// returns its value as a bit. If the field is unset, sets Unset to true and + /// retunrs false. + /// + bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const; + /// getValueAsInt - This method looks up the specified field and returns its /// value as an int64_t, throwing an exception if the field does not exist or /// if the value is not the right type. @@ -1601,6 +1761,16 @@ struct LessRecord { } }; +/// LessRecordByID - Sorting predicate to sort record pointers by their +/// unique ID. If you just need a deterministic order, use this, since it +/// just compares two `unsigned`; the other sorting predicates require +/// string manipulation. +struct LessRecordByID { + bool operator()(const Record *LHS, const Record *RHS) const { + return LHS->getID() < RHS->getID(); + } +}; + /// LessRecordFieldName - Sorting predicate to sort record pointers by their /// name field. /// diff --git a/include/llvm/TableGen/TableGenAction.h b/include/llvm/TableGen/TableGenAction.h deleted file mode 100644 index 733ae62..0000000 --- a/include/llvm/TableGen/TableGenAction.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- llvm/TableGen/TableGenAction.h - defines TableGenAction --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TableGenAction base class to be derived from by -// tblgen tools. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TABLEGEN_TABLEGENACTION_H -#define LLVM_TABLEGEN_TABLEGENACTION_H - -namespace llvm { - -class raw_ostream; -class RecordKeeper; - -class TableGenAction { - virtual void anchor(); -public: - virtual ~TableGenAction() {} - - /// Perform the action using Records, and write output to OS. - /// @returns true on error, false otherwise - virtual bool operator()(raw_ostream &OS, RecordKeeper &Records) = 0; -}; - -} - -#endif diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h index d5e165e..a50f54a 100644 --- a/include/llvm/Target/Mangler.h +++ b/include/llvm/Target/Mangler.h @@ -22,7 +22,7 @@ class GlobalValue; template <typename T> class SmallVectorImpl; class MCContext; class MCSymbol; -class TargetData; +class DataLayout; class Mangler { public: @@ -34,7 +34,7 @@ public: private: MCContext &Context; - const TargetData &TD; + const DataLayout &TD; /// AnonGlobalIDs - We need to give global values the same name every time /// they are mangled. This keeps track of the number we give to anonymous @@ -47,20 +47,19 @@ private: unsigned NextAnonGlobalID; public: - Mangler(MCContext &context, const TargetData &td) + Mangler(MCContext &context, const DataLayout &td) : Context(context), TD(td), NextAnonGlobalID(1) {} /// getSymbol - Return the MCSymbol for the specified global value. This /// symbol is the main label that is the address of the global. MCSymbol *getSymbol(const GlobalValue *GV); - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified global variable's name. If the global variable doesn't /// have a name, this fills in a unique name for the global. void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, bool isImplicitlyPrivate); - + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified name as the global variable name. GVName must not be /// empty. diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 1816445..12f5c0e 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -343,8 +343,8 @@ class Instruction { bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? - bit mayLoad = 0; // Is it possible for this inst to read memory? - bit mayStore = 0; // Is it possible for this inst to write memory? + bit mayLoad = ?; // Is it possible for this inst to read memory? + bit mayStore = ?; // Is it possible for this inst to write memory? bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? bit isCommutable = 0; // Is this 3 operand instruction commutable? bit isTerminator = 0; // Is this part of the terminator for a basic block? @@ -369,7 +369,7 @@ class Instruction { // // neverHasSideEffects - Set on an instruction with no pattern if it has no // side effects. - bit hasSideEffects = 0; + bit hasSideEffects = ?; bit neverHasSideEffects = 0; // Is this instruction a "real" instruction (with a distinct machine @@ -495,7 +495,8 @@ def ptr_rc : PointerLikeRegClass<0>; /// unknown definition - Mark this operand as being of unknown type, causing /// it to be resolved by inference in the context it is used. -def unknown; +class unknown_class; +def unknown : unknown_class; /// AsmOperandClass - Representation for the kinds of operands which the target /// specific parser can create and the assembly matcher may need to distinguish. @@ -602,23 +603,31 @@ def f64imm : Operand<f64>; /// def zero_reg; +/// OperandWithDefaultOps - This Operand class can be used as the parent class +/// for an Operand that needs to be initialized with a default value if +/// no value is supplied in a pattern. This class can be used to simplify the +/// pattern definitions for instructions that have target specific flags +/// encoded as immediate operands. +class OperandWithDefaultOps<ValueType ty, dag defaultops> + : Operand<ty> { + dag DefaultOps = defaultops; +} + /// PredicateOperand - This can be used to define a predicate operand for an /// instruction. OpTypes specifies the MIOperandInfo for the operand, and /// AlwaysVal specifies the value of this predicate when set to "always /// execute". class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal> - : Operand<ty> { + : OperandWithDefaultOps<ty, AlwaysVal> { let MIOperandInfo = OpTypes; - dag DefaultOps = AlwaysVal; } /// OptionalDefOperand - This is used to define a optional definition operand /// for an instruction. DefaultOps is the register the operand represents if /// none is supplied, e.g. zero_reg. class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops> - : Operand<ty> { + : OperandWithDefaultOps<ty, defaultops> { let MIOperandInfo = OpTypes; - dag DefaultOps = defaultops; } @@ -631,6 +640,17 @@ class InstrInfo { // Sparc manual specifies its instructions in the format [31..0] (big), while // PowerPC specifies them using the format [0..31] (little). bit isLittleEndianEncoding = 0; + + // The instruction properties mayLoad, mayStore, and hasSideEffects are unset + // by default, and TableGen will infer their value from the instruction + // pattern when possible. + // + // Normally, TableGen will issue an error it it can't infer the value of a + // property that hasn't been set explicitly. When guessInstructionProperties + // is set, it will guess a safe value instead. + // + // This option is a temporary migration help. It will go away. + bit guessInstructionProperties = 1; } // Standard Pseudo Instructions. @@ -734,6 +754,18 @@ def BUNDLE : Instruction { let InOperandList = (ins variable_ops); let AsmString = "BUNDLE"; } +def LIFETIME_START : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id); + let AsmString = "LIFETIME_START"; + let neverHasSideEffects = 1; +} +def LIFETIME_END : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id); + let AsmString = "LIFETIME_END"; + let neverHasSideEffects = 1; +} } //===----------------------------------------------------------------------===// @@ -753,6 +785,10 @@ class AsmParser { // function of the AsmParser class to call on every matched instruction. // This can be used to perform target specific instruction post-processing. string AsmParserInstCleanup = ""; + + //ShouldEmitMatchRegisterName - Set to false if the target needs a hand + //written register name matcher + bit ShouldEmitMatchRegisterName = 1; } def DefaultAsmParser : AsmParser; @@ -953,12 +989,64 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> { // ProcessorModel allows subtargets to specify the more general // SchedMachineModel instead if a ProcessorItinerary. Subtargets will // gradually move to this newer form. +// +// Although this class always passes NoItineraries to the Processor +// class, the SchedMachineModel may still define valid Itineraries. class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f> : Processor<n, NoItineraries, f> { let SchedModel = m; } //===----------------------------------------------------------------------===// +// InstrMapping - This class is used to create mapping tables to relate +// instructions with each other based on the values specified in RowFields, +// ColFields, KeyCol and ValueCols. +// +class InstrMapping { + // FilterClass - Used to limit search space only to the instructions that + // define the relationship modeled by this InstrMapping record. + string FilterClass; + + // RowFields - List of fields/attributes that should be same for all the + // instructions in a row of the relation table. Think of this as a set of + // properties shared by all the instructions related by this relationship + // model and is used to categorize instructions into subgroups. For instance, + // if we want to define a relation that maps 'Add' instruction to its + // predicated forms, we can define RowFields like this: + // + // let RowFields = BaseOp + // All add instruction predicated/non-predicated will have to set their BaseOp + // to the same value. + // + // def Add: { let BaseOp = 'ADD'; let predSense = 'nopred' } + // def Add_predtrue: { let BaseOp = 'ADD'; let predSense = 'true' } + // def Add_predfalse: { let BaseOp = 'ADD'; let predSense = 'false' } + list<string> RowFields = []; + + // List of fields/attributes that are same for all the instructions + // in a column of the relation table. + // Ex: let ColFields = 'predSense' -- It means that the columns are arranged + // based on the 'predSense' values. All the instruction in a specific + // column have the same value and it is fixed for the column according + // to the values set in 'ValueCols'. + list<string> ColFields = []; + + // Values for the fields/attributes listed in 'ColFields'. + // Ex: let KeyCol = 'nopred' -- It means that the key instruction (instruction + // that models this relation) should be non-predicated. + // In the example above, 'Add' is the key instruction. + list<string> KeyCol = []; + + // List of values for the fields/attributes listed in 'ColFields', one for + // each column in the relation table. + // + // Ex: let ValueCols = [['true'],['false']] -- It adds two columns in the + // table. First column requires all the instructions to have predSense + // set to 'true' and second column requires it to be 'false'. + list<list<string> > ValueCols = []; +} + +//===----------------------------------------------------------------------===// // Pull in the common support for calling conventions. // include "llvm/Target/TargetCallingConv.td" diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index f8cebef..2160e37 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -113,9 +113,18 @@ namespace ISD { MVT VT; bool Used; + /// Index original Function's argument. + unsigned OrigArgIndex; + + /// Offset in bytes of current input value relative to the beginning of + /// original argument. E.g. if argument was splitted into four 32 bit + /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12. + unsigned PartOffset; + InputArg() : VT(MVT::Other), Used(false) {} - InputArg(ArgFlagsTy flags, EVT vt, bool used) - : Flags(flags), Used(used) { + InputArg(ArgFlagsTy flags, EVT vt, bool used, + unsigned origIdx, unsigned partOffs) + : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) { VT = vt.getSimpleVT(); } }; @@ -131,9 +140,19 @@ namespace ISD { /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...". bool IsFixed; + /// Index original Function's argument. + unsigned OrigArgIndex; + + /// Offset in bytes of current output value relative to the beginning of + /// original argument. E.g. if argument was splitted into four 32 bit + /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12. + unsigned PartOffset; + OutputArg() : IsFixed(false) {} - OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed) - : Flags(flags), IsFixed(isfixed) { + OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed, + unsigned origIdx, unsigned partOffs) + : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx), + PartOffset(partOffs) { VT = vt.getSimpleVT(); } }; diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h deleted file mode 100644 index 5e48629..0000000 --- a/include/llvm/Target/TargetELFWriterInfo.h +++ /dev/null @@ -1,121 +0,0 @@ -//===-- llvm/Target/TargetELFWriterInfo.h - ELF Writer Info -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TargetELFWriterInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETELFWRITERINFO_H -#define LLVM_TARGET_TARGETELFWRITERINFO_H - -namespace llvm { - - //===--------------------------------------------------------------------===// - // TargetELFWriterInfo - //===--------------------------------------------------------------------===// - - class TargetELFWriterInfo { - protected: - // EMachine - This field is the target specific value to emit as the - // e_machine member of the ELF header. - unsigned short EMachine; - bool is64Bit, isLittleEndian; - public: - - // Machine architectures - enum MachineType { - EM_NONE = 0, // No machine - EM_M32 = 1, // AT&T WE 32100 - EM_SPARC = 2, // SPARC - EM_386 = 3, // Intel 386 - EM_68K = 4, // Motorola 68000 - EM_88K = 5, // Motorola 88000 - EM_486 = 6, // Intel 486 (deprecated) - EM_860 = 7, // Intel 80860 - EM_MIPS = 8, // MIPS R3000 - EM_PPC = 20, // PowerPC - EM_ARM = 40, // ARM - EM_ALPHA = 41, // DEC Alpha - EM_SPARCV9 = 43, // SPARC V9 - EM_X86_64 = 62, // AMD64 - EM_HEXAGON = 164 // Qualcomm Hexagon - }; - - // ELF File classes - enum { - ELFCLASS32 = 1, // 32-bit object file - ELFCLASS64 = 2 // 64-bit object file - }; - - // ELF Endianess - enum { - ELFDATA2LSB = 1, // Little-endian object file - ELFDATA2MSB = 2 // Big-endian object file - }; - - explicit TargetELFWriterInfo(bool is64Bit_, bool isLittleEndian_); - virtual ~TargetELFWriterInfo(); - - unsigned short getEMachine() const { return EMachine; } - unsigned getEFlags() const { return 0; } - unsigned getEIClass() const { return is64Bit ? ELFCLASS64 : ELFCLASS32; } - unsigned getEIData() const { - return isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB; - } - - /// ELF Header and ELF Section Header Info - unsigned getHdrSize() const { return is64Bit ? 64 : 52; } - unsigned getSHdrSize() const { return is64Bit ? 64 : 40; } - - /// Symbol Table Info - unsigned getSymTabEntrySize() const { return is64Bit ? 24 : 16; } - - /// getPrefELFAlignment - Returns the preferred alignment for ELF. This - /// is used to align some sections. - unsigned getPrefELFAlignment() const { return is64Bit ? 8 : 4; } - - /// getRelocationEntrySize - Entry size used in the relocation section - unsigned getRelocationEntrySize() const { - return is64Bit ? (hasRelocationAddend() ? 24 : 16) - : (hasRelocationAddend() ? 12 : 8); - } - - /// getRelocationType - Returns the target specific ELF Relocation type. - /// 'MachineRelTy' contains the object code independent relocation type - virtual unsigned getRelocationType(unsigned MachineRelTy) const = 0; - - /// hasRelocationAddend - True if the target uses an addend in the - /// ELF relocation entry. - virtual bool hasRelocationAddend() const = 0; - - /// getDefaultAddendForRelTy - Gets the default addend value for a - /// relocation entry based on the target ELF relocation type. - virtual long int getDefaultAddendForRelTy(unsigned RelTy, - long int Modifier = 0) const = 0; - - /// getRelTySize - Returns the size of relocatable field in bits - virtual unsigned getRelocationTySize(unsigned RelTy) const = 0; - - /// isPCRelativeRel - True if the relocation type is pc relative - virtual bool isPCRelativeRel(unsigned RelTy) const = 0; - - /// getJumpTableRelocationTy - Returns the machine relocation type used - /// to reference a jumptable. - virtual unsigned getAbsoluteLabelMachineRelTy() const = 0; - - /// computeRelocation - Some relocatable fields could be relocated - /// directly, avoiding the relocation symbol emission, compute the - /// final relocation value for this symbol. - virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset, - unsigned RelTy) const = 0; - }; - -} // end llvm namespace - -#endif // LLVM_TARGET_TARGETELFWRITERINFO_H diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index da30ab8..4570813 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -45,8 +45,8 @@ template<class T> class SmallVectorImpl; /// TargetInstrInfo - Interface to description of machine instruction set /// class TargetInstrInfo : public MCInstrInfo { - TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT - void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT + TargetInstrInfo(const TargetInstrInfo &) LLVM_DELETED_FUNCTION; + void operator=(const TargetInstrInfo &) LLVM_DELETED_FUNCTION; public: TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1) : CallFrameSetupOpcode(CFSetupOpcode), @@ -459,6 +459,13 @@ public: } /// copyPhysReg - Emit instructions to copy a pair of physical registers. + /// + /// This function should support copies within any legal register class as + /// well as any cross-class copies created during instruction selection. + /// + /// The source and destination registers may overlap, which may require a + /// careful implementation when multiple copy instructions are required for + /// large registers. See for example the ARM target. virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, @@ -794,29 +801,6 @@ public: const MachineInstr *UseMI, unsigned UseIdx, bool FindMin = false) const; - /// computeOperandLatency - Compute and return the latency of the given data - /// dependent def and use. DefMI must be a valid def. UseMI may be NULL for - /// an unknown use. If the subtarget allows, this may or may not need to call - /// getOperandLatency(). - /// - /// FindMin may be set to get the minimum vs. expected latency. Minimum - /// latency is used for scheduling groups, while expected latency is for - /// instruction cost and critical path. - unsigned computeOperandLatency(const InstrItineraryData *ItinData, - const TargetRegisterInfo *TRI, - const MachineInstr *DefMI, - const MachineInstr *UseMI, - unsigned Reg, bool FindMin) const; - - /// getOutputLatency - Compute and return the output dependency latency of a - /// a given pair of defs which both target the same register. This is usually - /// one. - virtual unsigned getOutputLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *DepMI) const { - return 1; - } - /// getInstrLatency - Compute the instruction latency of a given instruction. /// If the instruction has higher cost when predicated, it's returned via /// PredCost. @@ -831,6 +815,9 @@ public: unsigned defaultDefLatency(const MCSchedModel *SchedModel, const MachineInstr *DefMI) const; + int computeDefOperandLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, bool FindMin) const; + /// isHighLatencyDef - Return true if this opcode has high latency to its /// result. virtual bool isHighLatencyDef(int opc) const { return false; } diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h index c44b923..ce21349 100644 --- a/include/llvm/Target/TargetIntrinsicInfo.h +++ b/include/llvm/Target/TargetIntrinsicInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETINTRINSICINFO_H #define LLVM_TARGET_TARGETINTRINSICINFO_H +#include "llvm/Support/Compiler.h" #include <string> namespace llvm { @@ -27,8 +28,8 @@ class Type; /// TargetIntrinsicInfo - Interface to description of machine instruction set /// class TargetIntrinsicInfo { - TargetIntrinsicInfo(const TargetIntrinsicInfo &); // DO NOT IMPLEMENT - void operator=(const TargetIntrinsicInfo &); // DO NOT IMPLEMENT + TargetIntrinsicInfo(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION; + void operator=(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION; public: TargetIntrinsicInfo(); virtual ~TargetIntrinsicInfo(); diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index ea2874f..a2c97d7 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -18,6 +18,26 @@ namespace llvm { namespace LibFunc { enum Func { + /// void operator delete[](void*); + ZdaPv, + /// void operator delete(void*); + ZdlPv, + /// void *new[](unsigned int); + Znaj, + /// void *new[](unsigned int, nothrow); + ZnajRKSt9nothrow_t, + /// void *new[](unsigned long); + Znam, + /// void *new[](unsigned long, nothrow); + ZnamRKSt9nothrow_t, + /// void *new(unsigned int); + Znwj, + /// void *new(unsigned int, nothrow); + ZnwjRKSt9nothrow_t, + /// void *new(unsigned long); + Znwm, + /// void *new(unsigned long, nothrow); + ZnwmRKSt9nothrow_t, /// int __cxa_atexit(void (*f)(void *), void *p, void *d); cxa_atexit, /// void __cxa_guard_abort(guard_t *guard); @@ -33,12 +53,24 @@ namespace llvm { acos, /// float acosf(float x); acosf, + /// double acosh(double x); + acosh, + /// float acoshf(float x); + acoshf, + /// long double acoshl(long double x); + acoshl, /// long double acosl(long double x); acosl, /// double asin(double x); asin, /// float asinf(float x); asinf, + /// double asinh(double x); + asinh, + /// float asinhf(float x); + asinhf, + /// long double asinhl(long double x); + asinhl, /// long double asinl(long double x); asinl, /// double atan(double x); @@ -51,8 +83,22 @@ namespace llvm { atan2l, /// float atanf(float x); atanf, + /// double atanh(double x); + atanh, + /// float atanhf(float x); + atanhf, + /// long double atanhl(long double x); + atanhl, /// long double atanl(long double x); atanl, + /// void *calloc(size_t count, size_t size); + calloc, + /// double cbrt(double x); + cbrt, + /// float cbrtf(float x); + cbrtf, + /// long double cbrtl(long double x); + cbrtl, /// double ceil(double x); ceil, /// float ceilf(float x); @@ -79,6 +125,12 @@ namespace llvm { cosl, /// double exp(double x); exp, + /// double exp10(double x); + exp10, + /// float exp10f(float x); + exp10f, + /// long double exp10l(long double x); + exp10l, /// double exp2(double x); exp2, /// float exp2f(float x); @@ -119,6 +171,8 @@ namespace llvm { fputc, /// int fputs(const char *s, FILE *stream); fputs, + /// void free(void *ptr); + free, /// size_t fwrite(const void *ptr, size_t size, size_t nitems, /// FILE *stream); fwrite, @@ -144,10 +198,18 @@ namespace llvm { log2f, /// double long double log2l(long double x); log2l, + /// double logb(double x); + logb, + /// float logbf(float x); + logbf, + /// long double logbl(long double x); + logbl, /// float logf(float x); logf, /// long double logl(long double x); logl, + /// void *malloc(size_t size); + malloc, /// void *memchr(const void *s, int c, size_t n); memchr, /// int memcmp(const void *s1, const void *s2, size_t n); @@ -166,6 +228,8 @@ namespace llvm { nearbyintf, /// long double nearbyintl(long double x); nearbyintl, + /// int posix_memalign(void **memptr, size_t alignment, size_t size); + posix_memalign, /// double pow(double x, double y); pow, /// float powf(float x, float y); @@ -176,6 +240,10 @@ namespace llvm { putchar, /// int puts(const char *s); puts, + /// void *realloc(void *ptr, size_t size); + realloc, + /// void *reallocf(void *ptr, size_t size); + reallocf, /// double rint(double x); rint, /// float rintf(float x); @@ -208,12 +276,20 @@ namespace llvm { sqrtf, /// long double sqrtl(long double x); sqrtl, + /// char *stpcpy(char *s1, const char *s2); + stpcpy, /// char *strcat(char *s1, const char *s2); strcat, /// char *strchr(const char *s, int c); strchr, + /// int strcmp(const char *s1, const char *s2); + strcmp, /// char *strcpy(char *s1, const char *s2); strcpy, + /// size_t strcspn(const char *s1, const char *s2); + strcspn, + /// char *strdup(const char *s1); + strdup, /// size_t strlen(const char *s); strlen, /// char *strncat(char *s1, const char *s2, size_t n); @@ -222,8 +298,33 @@ namespace llvm { strncmp, /// char *strncpy(char *s1, const char *s2, size_t n); strncpy, + /// char *strndup(const char *s1, size_t n); + strndup, /// size_t strnlen(const char *s, size_t maxlen); strnlen, + /// char *strpbrk(const char *s1, const char *s2); + strpbrk, + /// char *strrchr(const char *s, int c); + strrchr, + /// size_t strspn(const char *s1, const char *s2); + strspn, + /// char *strstr(const char *s1, const char *s2); + strstr, + /// double strtod(const char *nptr, char **endptr); + strtod, + /// float strtof(const char *nptr, char **endptr); + strtof, + /// long int strtol(const char *nptr, char **endptr, int base); + strtol, + /// long double strtold(const char *nptr, char **endptr); + strtold, + /// long long int strtoll(const char *nptr, char **endptr, int base); + strtoll, + /// unsigned long int strtoul(const char *nptr, char **endptr, int base); + strtoul, + /// unsigned long long int strtoull(const char *nptr, char **endptr, + /// int base); + strtoull, /// double tan(double x); tan, /// float tanf(float x); @@ -242,6 +343,8 @@ namespace llvm { truncf, /// long double truncl(long double x); truncl, + /// void *valloc(size_t size); + valloc, NumLibFuncs }; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index acf0419..580a30f 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -22,9 +22,11 @@ #ifndef LLVM_TARGET_TARGETLOWERING_H #define LLVM_TARGET_TARGETLOWERING_H +#include "llvm/AddressingMode.h" #include "llvm/CallingConv.h" #include "llvm/InlineAsm.h" #include "llvm/Attributes.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/CallSite.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/RuntimeLibcalls.h" @@ -49,7 +51,7 @@ namespace llvm { class MCContext; class MCExpr; template<typename T> class SmallVectorImpl; - class TargetData; + class DataLayout; class TargetRegisterClass; class TargetLibraryInfo; class TargetLoweringObjectFile; @@ -76,8 +78,8 @@ namespace llvm { /// target-specific constructs to SelectionDAG operators. /// class TargetLowering { - TargetLowering(const TargetLowering&); // DO NOT IMPLEMENT - void operator=(const TargetLowering&); // DO NOT IMPLEMENT + TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION; + void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION; public: /// LegalizeAction - This enum indicates whether operations are valid for a /// target, and if not, what action should be used to make them valid. @@ -101,12 +103,24 @@ public: TypeWidenVector // This vector should be widened into a larger vector. }; + /// LegalizeKind holds the legalization kind that needs to happen to EVT + /// in order to type-legalize it. + typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind; + enum BooleanContent { // How the target represents true/false values. UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage. ZeroOrOneBooleanContent, // All bits zero except for bit 0. ZeroOrNegativeOneBooleanContent // All bits equal to bit 0. }; + enum SelectSupportKind { + ScalarValSelect, // The target supports scalar selects (ex: cmov). + ScalarCondVectorVal, // The target supports selects with a scalar condition + // and vector values (ex: cmov). + VectorMaskSelect // The target supports vector selects with a vector + // mask (ex: x86 blends). + }; + static ISD::NodeType getExtendForContent(BooleanContent Content) { switch (Content) { case UndefinedBooleanContent: @@ -128,22 +142,37 @@ public: virtual ~TargetLowering(); const TargetMachine &getTargetMachine() const { return TM; } - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return TD; } const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } - MVT getPointerTy() const { return PointerTy; } + // Return the pointer type for the given address space, defaults to + // the pointer type from the data layout. + // FIXME: The default needs to be removed once all the code is updated. + virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; } virtual MVT getShiftAmountTy(EVT LHSTy) const; /// isSelectExpensive - Return true if the select operation is expensive for /// this target. bool isSelectExpensive() const { return SelectIsExpensive; } + virtual bool isSelectSupported(SelectSupportKind kind) const { return true; } + /// isIntDivCheap() - Return true if integer divide is usually cheaper than /// a sequence of several shifts, adds, and multiplies for this target. bool isIntDivCheap() const { return IntDivIsCheap; } + /// isSlowDivBypassed - Returns true if target has indicated at least one + /// type should be bypassed. + bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); } + + /// getBypassSlowDivTypes - Returns map of slow types for division or + /// remainder with corresponding fast types + const DenseMap<unsigned int, unsigned int> &getBypassSlowDivWidths() const { + return BypassSlowDivWidths; + } + /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of /// srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } @@ -382,6 +411,13 @@ public: getOperationAction(Op, VT) == Custom); } + /// isOperationExpand - Return true if the specified operation is illegal on + /// this target or unlikely to be made legal with custom lowering. This is + /// used to help guide high-level lowering decisions. + bool isOperationExpand(unsigned Op, EVT VT) const { + return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand); + } + /// isOperationLegal - Return true if the specified operation is legal on this /// target. bool isOperationLegal(unsigned Op, EVT VT) const { @@ -475,8 +511,12 @@ public: assert((unsigned)CC < array_lengthof(CondCodeActions) && (unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0])*4 && "Table isn't big enough!"); + /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit + /// value and the upper 27 bits index into the second dimension of the + /// array to select what 64bit value to use. LegalizeAction Action = (LegalizeAction) - ((CondCodeActions[CC] >> (2*VT.getSimpleVT().SimpleTy)) & 3); + ((CondCodeActions[CC][VT.getSimpleVT().SimpleTy >> 5] + >> (2*(VT.getSimpleVT().SimpleTy & 0x1F))) & 3); assert(Action != Promote && "Can't promote condition code!"); return Action; } @@ -533,6 +573,7 @@ public: } return EVT::getEVT(Ty, AllowUnknown); } + /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate /// function arguments in the caller parameter area. This is the actual @@ -686,6 +727,12 @@ public: return SupportJumpTables; } + /// getMinimumJumpTableEntries - return integer threshold on number of + /// blocks to use jump tables rather than if sequence. + int getMinimumJumpTableEntries() const { + return MinimumJumpTableEntries; + } + /// getStackPointerRegisterToSaveRestore - If a physical register, this /// specifies the register that llvm.savestack/llvm.restorestack should save /// and restore. @@ -1006,6 +1053,12 @@ protected: SupportJumpTables = Val; } + /// setMinimumJumpTableEntries - Indicate the number of blocks to generate + /// jump tables rather than if sequence. + void setMinimumJumpTableEntries(int Val) { + MinimumJumpTableEntries = Val; + } + /// setStackPointerRegisterToSaveRestore - If set to a physical register, this /// specifies the register that llvm.savestack/llvm.restorestack should save /// and restore. @@ -1045,6 +1098,11 @@ protected: /// of instructions not containing an integer divide. void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; } + /// addBypassSlowDiv - Tells the code generator which bitwidths to bypass. + void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) { + BypassSlowDivWidths[SlowBitWidth] = FastBitWidth; + } + /// setPow2DivIsCheap - Tells the code generator that it shouldn't generate /// srl/add/sra for a signed divide by power of two, and let the target handle /// it. @@ -1127,8 +1185,13 @@ protected: assert(VT < MVT::LAST_VALUETYPE && (unsigned)CC < array_lengthof(CondCodeActions) && "Table isn't big enough!"); - CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.SimpleTy*2); - CondCodeActions[(unsigned)CC] |= (uint64_t)Action << VT.SimpleTy*2; + /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit + /// value and the upper 27 bits index into the second dimension of the + /// array to select what 64bit value to use. + CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] + &= ~(uint64_t(3UL) << (VT.SimpleTy & 0x1F)*2); + CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] + |= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2; } /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the @@ -1201,7 +1264,7 @@ protected: public: //===--------------------------------------------------------------------===// // Lowering methods - These methods must be implemented by targets so that - // the SelectionDAGLowering code knows how to lower these. + // the SelectionDAGBuilder code knows how to lower these. // /// LowerFormalArguments - This hook must be implemented to lower the @@ -1271,9 +1334,9 @@ public: FunctionType *FTy, bool isTailCall, SDValue callee, ArgListTy &args, SelectionDAG &dag, DebugLoc dl, ImmutableCallSite &cs) - : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)), - RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()), - IsInReg(cs.paramHasAttr(0, Attribute::InReg)), + : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attributes::SExt)), + RetZExt(cs.paramHasAttr(0, Attributes::ZExt)), IsVarArg(FTy->isVarArg()), + IsInReg(cs.paramHasAttr(0, Attributes::InReg)), DoesNotReturn(cs.doesNotReturn()), IsReturnValueUsed(!cs.getInstruction()->use_empty()), IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()), @@ -1314,7 +1377,7 @@ public: } /// HandleByVal - Target-specific cleanup for formal ByVal parameters. - virtual void HandleByVal(CCState *, unsigned &) const {} + virtual void HandleByVal(CCState *, unsigned &, unsigned) const {} /// CanLowerReturn - This hook should be implemented to check whether the /// return values described by the Outs array can fit into the return @@ -1584,22 +1647,6 @@ public: // Addressing mode description hooks (used by LSR etc). // - /// 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) {} - }; - /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the /// same BB as Load/Store instructions reading the address. This allows as /// much computation as possible to be done in the address mode for that @@ -1741,10 +1788,11 @@ public: private: const TargetMachine &TM; - const TargetData *TD; + const DataLayout *TD; const TargetLoweringObjectFile &TLOF; - /// PointerTy - The type to use for pointers, usually i32 or i64. + /// PointerTy - The type to use for pointers for the default address space, + /// usually i32 or i64. /// MVT PointerTy; @@ -1762,6 +1810,12 @@ private: /// set to true unconditionally. bool IntDivIsCheap; + /// BypassSlowDivMap - Tells the code generator to bypass slow divide or + /// remainder instructions. For example, BypassSlowDivWidths[32,8] tells the + /// code generator to bypass 32-bit integer div/rem with an 8-bit unsigned + /// integer div/rem when the operands are positive and less than 256. + DenseMap <unsigned int, unsigned int> BypassSlowDivWidths; + /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate /// srl/add/sra for a signed divide by power of two, and let the target handle /// it. @@ -1784,6 +1838,9 @@ private: /// If it's not true, then each jumptable must be lowered into if-then-else's. bool SupportJumpTables; + /// MinimumJumpTableEntries - Number of blocks threshold to use jump tables. + int MinimumJumpTableEntries; + /// BooleanContents - Information about the contents of the high-bits in /// boolean values held in a type wider than i1. See getBooleanContents. BooleanContent BooleanContents; @@ -1901,12 +1958,14 @@ private: /// CondCodeActions - For each condition code (ISD::CondCode) keep a /// LegalizeAction that indicates how instruction selection should /// deal with the condition code. - uint64_t CondCodeActions[ISD::SETCC_INVALID]; + /// Because each CC action takes up 2 bits, we need to have the array size + /// be large enough to fit all of the value types. This can be done by + /// dividing the MVT::LAST_VALUETYPE by 32 and adding one. + uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1]; ValueTypeActionImpl ValueTypeActions; - typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind; - +public: LegalizeKind getTypeConversion(LLVMContext &Context, EVT VT) const { // If this is a simple type, use the ComputeRegisterProp mechanism. @@ -1921,6 +1980,9 @@ private: ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger) && "Promote may not follow Expand or Promote"); + if (LA == TypeSplitVector) + NVT = EVT::getVectorVT(Context, VT.getVectorElementType(), + VT.getVectorNumElements() / 2); return LegalizeKind(LA, NVT); } @@ -2023,6 +2085,7 @@ private: return LegalizeKind(TypeSplitVector, NVT); } +private: std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses; /// TargetDAGCombineArray - Targets can specify ISD nodes that they would diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index d631f58..13a6fe3 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -33,10 +33,11 @@ namespace llvm { class TargetLoweringObjectFile : public MCObjectFileInfo { MCContext *Ctx; - - TargetLoweringObjectFile(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT - void operator=(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT - + + TargetLoweringObjectFile( + const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; + void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; + public: MCContext &getContext() const { return *Ctx; } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index e4bf32b..5006647 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -17,6 +17,8 @@ #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/TargetTransformInfo.h" +#include "llvm/Target/TargetTransformImpl.h" #include "llvm/ADT/StringRef.h" #include <cassert> #include <string> @@ -31,8 +33,7 @@ class MCCodeGenInfo; class MCContext; class PassManagerBase; class Target; -class TargetData; -class TargetELFWriterInfo; +class DataLayout; class TargetFrameLowering; class TargetInstrInfo; class TargetIntrinsicInfo; @@ -52,8 +53,8 @@ class raw_ostream; /// through this interface. /// class TargetMachine { - TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT - void operator=(const TargetMachine &); // DO NOT IMPLEMENT + TargetMachine(const TargetMachine &) LLVM_DELETED_FUNCTION; + void operator=(const TargetMachine &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. TargetMachine(const Target &T, StringRef TargetTriple, StringRef CPU, StringRef FS, const TargetOptions &Options); @@ -106,7 +107,11 @@ public: virtual const TargetFrameLowering *getFrameLowering() const { return 0; } virtual const TargetLowering *getTargetLowering() const { return 0; } virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; } - virtual const TargetData *getTargetData() const { return 0; } + virtual const DataLayout *getDataLayout() const { return 0; } + virtual const ScalarTargetTransformInfo* + getScalarTargetTransformInfo() const { return 0; } + virtual const VectorTargetTransformInfo* + getVectorTargetTransformInfo() const { return 0; } /// getMCAsmInfo - Return target specific asm information. /// @@ -142,11 +147,6 @@ public: return 0; } - /// getELFWriterInfo - If this target supports an ELF writer, return - /// information for it, otherwise return null. - /// - virtual const TargetELFWriterInfo *getELFWriterInfo() const { return 0; } - /// hasMCRelaxAll - Check whether all machine code instructions should be /// relaxed. bool hasMCRelaxAll() const { return MCRelaxAll; } diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index f0b181e..516e070 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -87,7 +87,11 @@ namespace TargetOpcode { /// BUNDLE - This instruction represents an instruction bundle. Instructions /// which immediately follow a BUNDLE instruction which are marked with /// 'InsideBundle' flag are inside the bundle. - BUNDLE + BUNDLE = 14, + + /// Lifetime markers. + LIFETIME_START = 15, + LIFETIME_END = 16 }; } // end namespace TargetOpcode } // end namespace llvm diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index d1a07d1..68ca567 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -155,6 +155,10 @@ namespace llvm { /// automatically realigned, if needed. unsigned RealignStack : 1; + /// SSPBufferSize - The minimum size of buffers that will receive stack + /// smashing protection when -fstack-protection is used. + unsigned SSPBufferSize; + /// EnableFastISel - This flag enables fast-path instruction selection /// which trades away generated code quality in favor of reducing /// compile time. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index df4d900..afa2ee2 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -221,13 +221,17 @@ public: private: const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. + // Pointer to array of lane masks, one per sub-reg index. + const unsigned *SubRegIndexLaneMasks; + regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses protected: TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, - const char *const *subregindexnames); + const char *const *SRINames, + const unsigned *SRILaneMasks); virtual ~TargetRegisterInfo(); public: @@ -327,10 +331,36 @@ public: /// getSubRegIndexName - Return the human-readable symbolic target-specific /// name for the specified SubRegIndex. const char *getSubRegIndexName(unsigned SubIdx) const { - assert(SubIdx && "This is not a subregister index"); + assert(SubIdx && SubIdx < getNumSubRegIndices() && + "This is not a subregister index"); return SubRegIndexNames[SubIdx-1]; } + /// getSubRegIndexLaneMask - Return a bitmask representing the parts of a + /// register that are covered by SubIdx. + /// + /// Lane masks for sub-register indices are similar to register units for + /// physical registers. The individual bits in a lane mask can't be assigned + /// any specific meaning. They can be used to check if two sub-register + /// indices overlap. + /// + /// If the target has a register such that: + /// + /// getSubReg(Reg, A) overlaps getSubReg(Reg, B) + /// + /// then: + /// + /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0 + /// + /// The converse is not necessarily true. If two lane masks have a common + /// bit, the corresponding sub-registers may not overlap, but it can be + /// assumed that they usually will. + unsigned getSubRegIndexLaneMask(unsigned SubIdx) const { + // SubIdx == 0 is allowed, it has the lane mask ~0u. + assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index"); + return SubRegIndexLaneMasks[SubIdx]; + } + /// regsOverlap - Returns true if the two registers are equal or alias each /// other. The registers may be virtual register. bool regsOverlap(unsigned regA, unsigned regB) const { @@ -416,18 +446,6 @@ public: return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC); } - /// canCombineSubRegIndices - Given a register class and a list of - /// subregister indices, return true if it's possible to combine the - /// subregister indices into one that corresponds to a larger - /// subregister. Return the new subregister index by reference. Note the - /// new index may be zero if the given subregisters can be combined to - /// form the whole register. - virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC, - SmallVectorImpl<unsigned> &SubIndices, - unsigned &NewSubIdx) const { - return 0; - } - /// getMatchingSuperRegClass - Return a subclass of the specified register /// class A so that each register in it has a sub-register of the /// specified sub-register index which is in the specified register class B. @@ -458,6 +476,8 @@ public: /// composeSubRegIndices - Return the subregister index you get from composing /// two subregister indices. /// + /// The special null sub-register index composes as the identity. + /// /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b) /// returns c. Note that composeSubRegIndices does not tell you about illegal /// compositions. If R does not have a subreg a, or R:a does not have a subreg @@ -467,11 +487,19 @@ public: /// ssub_0:S0 - ssub_3:S3 subregs. /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2. /// - virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const { - // This default implementation is correct for most targets. - return b; + unsigned composeSubRegIndices(unsigned a, unsigned b) const { + if (!a) return b; + if (!b) return a; + return composeSubRegIndicesImpl(a, b); } +protected: + /// Overridden by TableGen in targets that have sub-registers. + virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const { + llvm_unreachable("Target has no sub-registers"); + } + +public: /// getCommonSuperRegClass - Find a common super-register class if it exists. /// /// Find a register class, SuperRC and two sub-register indices, PreA and diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 4dc488d..0da82fd 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -10,25 +10,77 @@ // This file defines the target-independent scheduling interfaces which should // be implemented by each target which is using TableGen based scheduling. // +// The SchedMachineModel is defined by subtargets for three categories of data: +// 1. Basic properties for coarse grained instruction cost model. +// 2. Scheduler Read/Write resources for simple per-opcode cost model. +// 3. Instruction itineraties for detailed reservation tables. +// +// (1) Basic properties are defined by the SchedMachineModel +// class. Target hooks allow subtargets to associate opcodes with +// those properties. +// +// (2) A per-operand machine model can be implemented in any +// combination of the following ways: +// +// A. Associate per-operand SchedReadWrite types with Instructions by +// modifying the Instruction definition to inherit from Sched. For +// each subtarget, define WriteRes and ReadAdvance to associate +// processor resources and latency with each SchedReadWrite type. +// +// B. In each instruction definition, name an ItineraryClass. For each +// subtarget, define ItinRW entries to map ItineraryClass to +// per-operand SchedReadWrite types. Unlike method A, these types may +// be subtarget specific and can be directly associated with resources +// by defining SchedWriteRes and SchedReadAdvance. +// +// C. In the subtarget, map SchedReadWrite types to specific +// opcodes. This overrides any SchedReadWrite types or +// ItineraryClasses defined by the Instruction. As in method B, the +// subtarget can directly associate resources with SchedReadWrite +// types by defining SchedWriteRes and SchedReadAdvance. +// +// D. In either the target or subtarget, define SchedWriteVariant or +// SchedReadVariant to map one SchedReadWrite type onto another +// sequence of SchedReadWrite types. This allows dynamic selection of +// an instruction's machine model via custom C++ code. It also allows +// a machine-independent SchedReadWrite type to map to a sequence of +// machine-dependent types. +// +// (3) A per-pipeline-stage machine model can be implemented by providing +// Itineraries in addition to mapping instructions to ItineraryClasses. //===----------------------------------------------------------------------===// +// Include legacy support for instruction itineraries. include "llvm/Target/TargetItinerary.td" -// The SchedMachineModel is defined by subtargets for three categories of data: -// 1) Basic properties for coarse grained instruction cost model. -// 2) Scheduler Read/Write resources for simple per-opcode cost model. -// 3) Instruction itineraties for detailed reservation tables. +class Instruction; // Forward def + +// DAG operator that interprets the DAG args as Instruction defs. +def instrs; + +// DAG operator that interprets each DAG arg as a regex pattern for +// matching Instruction opcode names. +// The regex must match the beginning of the opcode (as in Python re.match). +// To avoid matching prefixes, append '$' to the pattern. +def instregex; + +// Define the SchedMachineModel and provide basic properties for +// coarse grained instruction cost model. Default values for the +// properties are defined in MCSchedModel. A value of "-1" in the +// target description's SchedMachineModel indicates that the property +// is not overriden by the target. // -// Default values for basic properties are defined in MCSchedModel. "-1" -// indicates that the property is not overriden by the target description. +// Target hooks allow subtargets to associate LoadLatency and +// HighLatency with groups of opcodes. class SchedMachineModel { - int IssueWidth = -1; // Max instructions that may be scheduled per cycle. + int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. int MinLatency = -1; // Determines which instrucions are allowed in a group. // (-1) inorder (0) ooo, (1): inorder +var latencies. int LoadLatency = -1; // Cycles for loads to access the cache. int HighLatency = -1; // Approximation of cycles for "high latency" ops. int MispredictPenalty = -1; // Extra cycles for a mispredicted branch. + // Per-cycle resources tables. ProcessorItineraries Itineraries = NoItineraries; bit NoModel = 0; // Special tag to indicate missing machine model. @@ -38,4 +90,276 @@ def NoSchedModel : SchedMachineModel { let NoModel = 1; } -// TODO: Define classes for processor and scheduler resources. +// Define a kind of processor resource that may be common across +// similar subtargets. +class ProcResourceKind; + +// Define a number of interchangeable processor resources. NumUnits +// determines the throughput of instructions that require the resource. +// +// An optional Super resource may be given to model these resources as +// a subset of the more general super resources. Using one of these +// resources implies using one of the super resoruces. +// +// ProcResourceUnits normally model a few buffered resources within an +// out-of-order engine that the compiler attempts to conserve. +// Buffered resources may be held for multiple clock cycles, but the +// scheduler does not pin them to a particular clock cycle relative to +// instruction dispatch. Setting Buffered=0 changes this to an +// in-order resource. In this case, the scheduler counts down from the +// cycle that the instruction issues in-order, forcing an interlock +// with subsequent instructions that require the same resource until +// the number of ResourceCyles specified in WriteRes expire. +// +// SchedModel ties these units to a processor for any stand-alone defs +// of this class. Instances of subclass ProcResource will be automatically +// attached to a processor, so SchedModel is not needed. +class ProcResourceUnits<ProcResourceKind kind, int num> { + ProcResourceKind Kind = kind; + int NumUnits = num; + ProcResourceKind Super = ?; + bit Buffered = 1; + SchedMachineModel SchedModel = ?; +} + +// EponymousProcResourceKind helps implement ProcResourceUnits by +// allowing a ProcResourceUnits definition to reference itself. It +// should not be referenced anywhere else. +def EponymousProcResourceKind : ProcResourceKind; + +// Subtargets typically define processor resource kind and number of +// units in one place. +class ProcResource<int num> : ProcResourceKind, + ProcResourceUnits<EponymousProcResourceKind, num>; + +// A target architecture may define SchedReadWrite types and associate +// them with instruction operands. +class SchedReadWrite; + +// List the per-operand types that map to the machine model of an +// instruction. One SchedWrite type must be listed for each explicit +// def operand in order. Additional SchedWrite types may optionally be +// listed for implicit def operands. SchedRead types may optionally +// be listed for use operands in order. The order of defs relative to +// uses is insignificant. This way, the same SchedReadWrite list may +// be used for multiple forms of an operation. For example, a +// two-address instruction could have two tied operands or single +// operand that both reads and writes a reg. In both cases we have a +// single SchedWrite and single SchedRead in any order. +class Sched<list<SchedReadWrite> schedrw> { + list<SchedReadWrite> SchedRW = schedrw; +} + +// Define a scheduler resource associated with a def operand. +class SchedWrite : SchedReadWrite; +def NoWrite : SchedWrite; + +// Define a scheduler resource associated with a use operand. +class SchedRead : SchedReadWrite; + +// Define a SchedWrite that is modeled as a sequence of other +// SchedWrites with additive latency. This allows a single operand to +// be mapped the resources composed from a set of previously defined +// SchedWrites. +// +// If the final write in this sequence is a SchedWriteVariant marked +// Variadic, then the list of prior writes are distributed across all +// operands after resolving the predicate for the final write. +// +// SchedModel silences warnings but is ignored. +class WriteSequence<list<SchedWrite> writes, int rep = 1> : SchedWrite { + list<SchedWrite> Writes = writes; + int Repeat = rep; + SchedMachineModel SchedModel = ?; +} + +// Define values common to WriteRes and SchedWriteRes. +// +// SchedModel ties these resources to a processor. +class ProcWriteResources<list<ProcResourceKind> resources> { + list<ProcResourceKind> ProcResources = resources; + list<int> ResourceCycles = []; + int Latency = 1; + int NumMicroOps = 1; + bit BeginGroup = 0; + bit EndGroup = 0; + // Allow a processor to mark some scheduling classes as unsupported + // for stronger verification. + bit Unsupported = 0; + SchedMachineModel SchedModel = ?; +} + +// Define the resources and latency of a SchedWrite. This will be used +// directly by targets that have no itinerary classes. In this case, +// SchedWrite is defined by the target, while WriteResources is +// defined by the subtarget, and maps the SchedWrite to processor +// resources. +// +// If a target already has itinerary classes, SchedWriteResources can +// be used instead to define subtarget specific SchedWrites and map +// them to processor resources in one place. Then ItinRW can map +// itinerary classes to the subtarget's SchedWrites. +// +// ProcResources indicates the set of resources consumed by the write. +// Optionally, ResourceCycles indicates the number of cycles the +// resource is consumed. Each ResourceCycles item is paired with the +// ProcResource item at the same position in its list. Since +// ResourceCycles are rarely specialized, the list may be +// incomplete. By default, resources are consumed for a single cycle, +// regardless of latency, which models a fully pipelined processing +// unit. A value of 0 for ResourceCycles means that the resource must +// be available but is not consumed, which is only relevant for +// unbuffered resources. +// +// By default, each SchedWrite takes one micro-op, which is counted +// against the processor's IssueWidth limit. If an instruction can +// write multiple registers with a single micro-op, the subtarget +// should define one of the writes to be zero micro-ops. If a +// subtarget requires multiple micro-ops to write a single result, it +// should either override the write's NumMicroOps to be greater than 1 +// or require additional writes. Extra writes can be required either +// by defining a WriteSequence, or simply listing extra writes in the +// instruction's list of writers beyond the number of "def" +// operands. The scheduler assumes that all micro-ops must be +// dispatched in the same cycle. These micro-ops may be required to +// begin or end the current dispatch group. +class WriteRes<SchedWrite write, list<ProcResourceKind> resources> + : ProcWriteResources<resources> { + SchedWrite WriteType = write; +} + +// Directly name a set of WriteResources defining a new SchedWrite +// type at the same time. This class is unaware of its SchedModel so +// must be referenced by InstRW or ItinRW. +class SchedWriteRes<list<ProcResourceKind> resources> : SchedWrite, + ProcWriteResources<resources>; + +// Define values common to ReadAdvance and SchedReadAdvance. +// +// SchedModel ties these resources to a processor. +class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> { + int Cycles = cycles; + list<SchedWrite> ValidWrites = writes; + // Allow a processor to mark some scheduling classes as unsupported + // for stronger verification. + bit Unsupported = 0; + SchedMachineModel SchedModel = ?; +} + +// A processor may define a ReadAdvance associated with a SchedRead +// to reduce latency of a prior write by N cycles. A negative advance +// effectively increases latency, which may be used for cross-domain +// stalls. +// +// A ReadAdvance may be associated with a list of SchedWrites +// to implement pipeline bypass. The Writes list may be empty to +// indicate operands that are always read this number of Cycles later +// than a normal register read, allowing the read's parent instruction +// to issue earlier relative to the writer. +class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []> + : ProcReadAdvance<cycles, writes> { + SchedRead ReadType = read; +} + +// Directly associate a new SchedRead type with a delay and optional +// pipeline bypess. For use with InstRW or ItinRW. +class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead, + ProcReadAdvance<cycles, writes>; + +// Define SchedRead defaults. Reads seldom need special treatment. +def ReadDefault : SchedRead; +def NoReadAdvance : SchedReadAdvance<0>; + +// Define shared code that will be in the same scope as all +// SchedPredicates. Available variables are: +// (const MachineInstr *MI, const TargetSchedModel *SchedModel) +class PredicateProlog<code c> { + code Code = c; +} + +// Define a predicate to determine which SchedVariant applies to a +// particular MachineInstr. The code snippet is used as an +// if-statement's expression. Available variables are MI, SchedModel, +// and anything defined in a PredicateProlog. +// +// SchedModel silences warnings but is ignored. +class SchedPredicate<code pred> { + SchedMachineModel SchedModel = ?; + code Predicate = pred; +} +def NoSchedPred : SchedPredicate<[{true}]>; + +// Associate a predicate with a list of SchedReadWrites. By default, +// the selected SchedReadWrites are still associated with a single +// operand and assumed to execute sequentially with additive +// latency. However, if the parent SchedWriteVariant or +// SchedReadVariant is marked "Variadic", then each Selected +// SchedReadWrite is mapped in place to the instruction's variadic +// operands. In this case, latency is not additive. If the current Variant +// is already part of a Sequence, then that entire chain leading up to +// the Variant is distributed over the variadic operands. +class SchedVar<SchedPredicate pred, list<SchedReadWrite> selected> { + SchedPredicate Predicate = pred; + list<SchedReadWrite> Selected = selected; +} + +// SchedModel silences warnings but is ignored. +class SchedVariant<list<SchedVar> variants> { + list<SchedVar> Variants = variants; + bit Variadic = 0; + SchedMachineModel SchedModel = ?; +} + +// A SchedWriteVariant is a single SchedWrite type that maps to a list +// of SchedWrite types under the conditions defined by its predicates. +// +// A Variadic write is expanded to cover multiple "def" operands. The +// SchedVariant's Expansion list is then interpreted as one write +// per-operand instead of the usual sequential writes feeding a single +// operand. +class SchedWriteVariant<list<SchedVar> variants> : SchedWrite, + SchedVariant<variants> { +} + +// A SchedReadVariant is a single SchedRead type that maps to a list +// of SchedRead types under the conditions defined by its predicates. +// +// A Variadic write is expanded to cover multiple "readsReg" operands as +// explained above. +class SchedReadVariant<list<SchedVar> variants> : SchedRead, + SchedVariant<variants> { +} + +// Map a set of opcodes to a list of SchedReadWrite types. This allows +// the subtarget to easily override specific operations. +// +// SchedModel ties this opcode mapping to a processor. +class InstRW<list<SchedReadWrite> rw, dag instrlist> { + list<SchedReadWrite> OperandReadWrites = rw; + dag Instrs = instrlist; + SchedMachineModel SchedModel = ?; +} + +// Map a set of itinerary classes to SchedReadWrite resources. This is +// used to bootstrap a target (e.g. ARM) when itineraries already +// exist and changing InstrInfo is undesirable. +// +// SchedModel ties this ItineraryClass mapping to a processor. +class ItinRW<list<SchedReadWrite> rw, list<InstrItinClass> iic> { + list<InstrItinClass> MatchedItinClasses = iic; + list<SchedReadWrite> OperandReadWrites = rw; + SchedMachineModel SchedModel = ?; +} + +// Alias a target-defined SchedReadWrite to a processor specific +// SchedReadWrite. This allows a subtarget to easily map a +// SchedReadWrite type onto a WriteSequence, SchedWriteVariant, or +// SchedReadVariant. +// +// SchedModel will usually be provided by surrounding let statement +// and ties this SchedAlias mapping to a processor. +class SchedAlias<SchedReadWrite match, SchedReadWrite alias> { + SchedReadWrite MatchRW = match; + SchedReadWrite AliasRW = alias; + SchedMachineModel SchedModel = ?; +} diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 3f81c06..83bd787 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -445,9 +445,9 @@ def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; + [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h index c9ca722..96793bc 100644 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -20,7 +20,7 @@ namespace llvm { -class TargetData; +class DataLayout; class TargetMachine; //===----------------------------------------------------------------------===// @@ -28,13 +28,13 @@ class TargetMachine; /// SelectionDAG lowering and instruction selection process. /// class TargetSelectionDAGInfo { - TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT - void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT + TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION; + void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION; - const TargetData *TD; + const DataLayout *TD; protected: - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return TD; } public: explicit TargetSelectionDAGInfo(const TargetMachine &TM); diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index fc23b2c..6db96d9 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -19,9 +19,11 @@ namespace llvm { +class MachineInstr; class SDep; class SUnit; class TargetRegisterClass; +class TargetSchedModel; template <typename T> class SmallVectorImpl; //===----------------------------------------------------------------------===// @@ -31,8 +33,8 @@ template <typename T> class SmallVectorImpl; /// be exposed through a TargetSubtargetInfo-derived class. /// class TargetSubtargetInfo : public MCSubtargetInfo { - TargetSubtargetInfo(const TargetSubtargetInfo&); // DO NOT IMPLEMENT - void operator=(const TargetSubtargetInfo&); // DO NOT IMPLEMENT + TargetSubtargetInfo(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION; + void operator=(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses... TargetSubtargetInfo(); public: @@ -43,23 +45,26 @@ public: virtual ~TargetSubtargetInfo(); - /// getSpecialAddressLatency - For targets where it is beneficial to - /// backschedule instructions that compute addresses, return a value - /// indicating the number of scheduling cycles of backscheduling that - /// should be attempted. - virtual unsigned getSpecialAddressLatency() const { return 0; } + /// Resolve a SchedClass at runtime, where SchedClass identifies an + /// MCSchedClassDesc with the isVariant property. This may return the ID of + /// another variant SchedClass, but repeated invocation must quickly terminate + /// in a nonvariant SchedClass. + virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, + const TargetSchedModel* SchedModel) const { + return 0; + } // enablePostRAScheduler - If the target can benefit from post-regalloc // scheduling and the specified optimization level meets the requirement // return true to enable post-register-allocation scheduling. In // CriticalPathRCs return any register classes that should only be broken - // if on the critical path. + // if on the critical path. virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, AntiDepBreakMode& Mode, RegClassVector& CriticalPathRCs) const; // adjustSchedDependency - Perform target specific adjustments to // the latency of a schedule dependency. - virtual void adjustSchedDependency(SUnit *def, SUnit *use, + virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep& dep) const { } }; diff --git a/include/llvm/Target/TargetTransformImpl.h b/include/llvm/Target/TargetTransformImpl.h new file mode 100644 index 0000000..7ea2396 --- /dev/null +++ b/include/llvm/Target/TargetTransformImpl.h @@ -0,0 +1,98 @@ +//=- llvm/Target/TargetTransformImpl.h - Target Loop Trans Info----*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the target-specific implementations of the +// TargetTransform interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H +#define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H + +#include "llvm/TargetTransformInfo.h" +#include "llvm/CodeGen/ValueTypes.h" + +namespace llvm { + +class TargetLowering; + +/// ScalarTargetTransformInfo - This is a default implementation for the +/// ScalarTargetTransformInfo interface. Different targets can implement +/// this interface differently. +class ScalarTargetTransformImpl : public ScalarTargetTransformInfo { +private: + const TargetLowering *TLI; + +public: + /// Ctor + explicit ScalarTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} + + virtual bool isLegalAddImmediate(int64_t imm) const; + + virtual bool isLegalICmpImmediate(int64_t imm) const; + + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; + + virtual bool isTypeLegal(Type *Ty) const; + + virtual unsigned getJumpBufAlignment() const; + + virtual unsigned getJumpBufSize() const; + + virtual bool shouldBuildLookupTables() const; +}; + +class VectorTargetTransformImpl : public VectorTargetTransformInfo { +protected: + const TargetLowering *TLI; + + /// Estimate the cost of type-legalization and the legalized type. + std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; + + /// Estimate the overhead of scalarizing an instruction. Insert and Extract + /// are set if the result needs to be inserted and/or extracted from vectors. + unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; + + // Get the ISD node that corresponds to the Instruction class opcode. + int InstructionOpcodeToISD(unsigned Opcode) const; + +public: + explicit VectorTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} + + virtual ~VectorTargetTransformImpl() {} + + virtual unsigned getInstrCost(unsigned Opcode, Type *Ty1, Type *Ty2) const; + + virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const; + + virtual unsigned getBroadcastCost(Type *Tp) const; + + virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const; + + virtual unsigned getCFInstrCost(unsigned Opcode) const; + + virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy) const; + + virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index) const; + + virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const; + + virtual unsigned getNumberOfParts(Type *Tp) const; +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/TargetTransformInfo.h b/include/llvm/TargetTransformInfo.h new file mode 100644 index 0000000..94db490 --- /dev/null +++ b/include/llvm/TargetTransformInfo.h @@ -0,0 +1,204 @@ +//===- llvm/Transforms/TargetTransformInfo.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass exposes codegen information to IR-level passes. Every +// transformation that uses codegen information is broken into three parts: +// 1. The IR-level analysis pass. +// 2. The IR-level transformation interface which provides the needed +// information. +// 3. Codegen-level implementation which uses target-specific hooks. +// +// This file defines #2, which is the interface that IR-level transformations +// use for querying the codegen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE +#define LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE + +#include "llvm/Pass.h" +#include "llvm/AddressingMode.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Type.h" + +namespace llvm { + +class ScalarTargetTransformInfo; +class VectorTargetTransformInfo; + +/// TargetTransformInfo - This pass provides access to the codegen +/// interfaces that are needed for IR-level transformations. +class TargetTransformInfo : public ImmutablePass { +private: + const ScalarTargetTransformInfo *STTI; + const VectorTargetTransformInfo *VTTI; +public: + /// Default ctor. + /// + /// @note This has to exist, because this is a pass, but it should never be + /// used. + TargetTransformInfo(); + + TargetTransformInfo(const ScalarTargetTransformInfo* S, + const VectorTargetTransformInfo *V) + : ImmutablePass(ID), STTI(S), VTTI(V) { + initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry()); + } + + TargetTransformInfo(const TargetTransformInfo &T) : + ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { } + + const ScalarTargetTransformInfo* getScalarTargetTransformInfo() const { + return STTI; + } + const VectorTargetTransformInfo* getVectorTargetTransformInfo() const { + return VTTI; + } + + /// Pass identification, replacement for typeid. + static char ID; +}; + +// ---------------------------------------------------------------------------// +// The classes below are inherited and implemented by target-specific classes +// in the codegen. +// ---------------------------------------------------------------------------// + +/// ScalarTargetTransformInfo - This interface is used by IR-level passes +/// that need target-dependent information for generic scalar transformations. +/// LSR, and LowerInvoke use this interface. +class ScalarTargetTransformInfo { +public: + virtual ~ScalarTargetTransformInfo() {} + + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t) const { + return false; + } + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(int64_t) const { + return false; + } + /// isLegalAddressingMode - Return true if the addressing mode represented by + /// AM is legal for this target, for a load/store of the specified type. + /// The type may be VoidTy, in which case only return true if the addressing + /// mode is legal for a load/store of any legal type. + /// TODO: Handle pre/postinc as well. + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const { + return false; + } + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const { + return false; + } + /// Is this type legal. + virtual bool isTypeLegal(Type *Ty) const { + return false; + } + /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes + virtual unsigned getJumpBufAlignment() const { + return 0; + } + /// getJumpBufSize - returns the target's jmp_buf size in bytes. + virtual unsigned getJumpBufSize() const { + return 0; + } + /// shouldBuildLookupTables - Return true if switches should be turned into + /// lookup tables for the target. + virtual bool shouldBuildLookupTables() const { + return true; + } +}; + +/// VectorTargetTransformInfo - This interface is used by the vectorizers +/// to estimate the profitability of vectorization for different instructions. +class VectorTargetTransformInfo { +public: + virtual ~VectorTargetTransformInfo() {} + + /// Returns the expected cost of the instruction opcode. The opcode is one of + /// the enums like Instruction::Add. The type arguments are the type of the + /// operation. + /// Most instructions only use the first type and in that case the second + /// operand is ignored. + /// + /// Exceptions: + /// * Br instructions do not use any of the types. + /// * Select instructions pass the return type as Ty1 and the selector as Ty2. + /// * Cast instructions pass the destination as Ty1 and the source as Ty2. + /// * Insert/Extract element pass only the vector type as Ty1. + /// * ShuffleVector, Load, Store do not use this call. + virtual unsigned getInstrCost(unsigned Opcode, + Type *Ty1 = 0, + Type *Ty2 = 0) const { + return 1; + } + + /// Returns the expected cost of arithmetic ops, such as mul, xor, fsub, etc. + virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { + return 1; + } + + /// Returns the cost of a vector broadcast of a scalar at place zero to a + /// vector of type 'Tp'. + virtual unsigned getBroadcastCost(Type *Tp) const { + return 1; + } + + /// Returns the expected cost of cast instructions, such as bitcast, trunc, + /// zext, etc. + virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const { + return 1; + } + + /// Returns the expected cost of control-flow related instrutctions such as + /// Phi, Ret, Br. + virtual unsigned getCFInstrCost(unsigned Opcode) const { + return 1; + } + + /// Returns the expected cost of compare and select instructions. + virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy = 0) const { + return 1; + } + + /// Returns the expected cost of vector Insert and Extract. + /// Use -1 to indicate that there is no information on the index value. + virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index = -1) const { + return 1; + } + + /// Returns the cost of Load and Store instructions. + virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const { + return 1; + } + + /// Returns the number of pieces into which the provided type must be + /// split during legalization. Zero is returned when the answer is unknown. + virtual unsigned getNumberOfParts(Type *Tp) const { + return 0; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 18176e8..fc1cd59 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -104,23 +104,14 @@ Pass *createPruneEHPass(); //===----------------------------------------------------------------------===// /// createInternalizePass - This pass loops over all of the functions in the -/// input module, internalizing all globals (functions and variables) not part -/// of the api. If a list of symbols is specified with the -/// -internalize-public-api-* command line options, those symbols are not -/// internalized and all others are. Otherwise if AllButMain is set and the -/// main function is found, all other globals are marked as internal. If no api -/// is supplied and AllButMain is not set, or no main function is found, nothing -/// is internalized. -/// -ModulePass *createInternalizePass(bool AllButMain); - -/// createInternalizePass - This pass loops over all of the functions in the /// input module, internalizing all globals (functions and variables) not in the /// given exportList. /// /// Note that commandline options that are used with the above function are not -/// used now! Also, when exportList is empty, nothing is internalized. +/// used now! ModulePass *createInternalizePass(const std::vector<const char *> &exportList); +/// createInternalizePass - Same as above, but with an empty exportList. +ModulePass *createInternalizePass(); //===----------------------------------------------------------------------===// /// createDeadArgEliminationPass - This pass removes arguments from functions @@ -192,6 +183,16 @@ ModulePass *createMergeFunctionsPass(); /// createPartialInliningPass - This pass inlines parts of functions. /// ModulePass *createPartialInliningPass(); + +//===----------------------------------------------------------------------===// +// createMetaRenamerPass - Rename everything with metasyntatic names. +// +ModulePass *createMetaRenamerPass(); + +//===----------------------------------------------------------------------===// +/// createBarrierNoopPass - This pass is purely a module pass barrier in a pass +/// manager. +ModulePass *createBarrierNoopPass(); } // End llvm namespace diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index 7c3cfc8..b036040 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -21,7 +21,7 @@ namespace llvm { class CallSite; - class TargetData; + class DataLayout; class InlineCost; template<class PtrType, unsigned SmallSize> class SmallPtrSet; diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index 47ce902..3ea0a42 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -104,6 +104,7 @@ public: bool DisableUnitAtATime; bool DisableUnrollLoops; bool Vectorize; + bool LoopVectorize; private: /// ExtensionList - This is list of all of the extensions that are registered. diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 4b0c448..8e63aaa 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -34,7 +34,7 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, bool UseExtraChecksum = false); // Insert AddressSanitizer (address sanity checking) instrumentation -ModulePass *createAddressSanitizerPass(); +FunctionPass *createAddressSanitizerPass(); // Insert ThreadSanitizer (race detection) instrumentation FunctionPass *createThreadSanitizerPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 3dce6fe..a5d8eed 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -70,6 +70,12 @@ FunctionPass *createAggressiveDCEPass(); //===----------------------------------------------------------------------===// // +// SROA - Replace aggregates or pieces of aggregates with scalar SSA values. +// +FunctionPass *createSROAPass(bool RequiresDomTree = true); + +//===----------------------------------------------------------------------===// +// // ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas // if possible. // diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h index 90485eb..7d67283 100644 --- a/include/llvm/Transforms/Utils/AddrModeMatcher.h +++ b/include/llvm/Transforms/Utils/AddrModeMatcher.h @@ -19,6 +19,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H #define LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H +#include "llvm/AddressingMode.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Target/TargetLowering.h" @@ -33,7 +34,7 @@ class raw_ostream; /// ExtAddrMode - This is an extended version of TargetLowering::AddrMode /// which holds actual Value*'s for register values. -struct ExtAddrMode : public TargetLowering::AddrMode { +struct ExtAddrMode : public AddrMode { Value *BaseReg; Value *ScaledReg; ExtAddrMode() : BaseReg(0), ScaledReg(0) {} diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 8a939cc..b810f1a 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -25,8 +25,11 @@ namespace llvm { class AliasAnalysis; class Instruction; +class MDNode; class Pass; class ReturnInst; +class TargetLibraryInfo; +class TerminatorInst; /// DeleteDeadBlock - Delete the specified block, which must have no /// predecessors. @@ -44,7 +47,7 @@ void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = 0); /// a result. This includes tracing the def-use list from the PHI to see if /// it is ultimately unused or if it reaches an unused cycle. Return true /// if any PHIs were deleted. -bool DeleteDeadPHIs(BasicBlock *BB); +bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = 0); /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. @@ -202,6 +205,29 @@ void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds, ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred); +/// SplitBlockAndInsertIfThen - Split the containing block at the +/// specified instruction - everything before and including Cmp stays +/// in the old basic block, and everything after Cmp is moved to a +/// new block. The two blocks are connected by a conditional branch +/// (with value of Cmp being the condition). +/// Before: +/// Head +/// Cmp +/// Tail +/// After: +/// Head +/// Cmp +/// if (Cmp) +/// ThenBlock +/// Tail +/// +/// If Unreachable is true, then ThenBlock ends with +/// UnreachableInst, otherwise it branches to Tail. +/// Returns the NewBasicBlock's terminator. + +TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp, + bool Unreachable, MDNode *BranchWeights = 0); + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h index a6e41f0..ab9fc47 100644 --- a/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -19,7 +19,7 @@ namespace llvm { class Value; - class TargetData; + class DataLayout; class TargetLibraryInfo; /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. @@ -28,52 +28,52 @@ namespace llvm { /// EmitStrLen - Emit a call to the strlen function to the builder, for the /// specified pointer. Ptr is required to be some pointer type, and the /// return value has 'intptr_t' type. - Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD, + Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the /// specified pointer. Ptr is required to be some pointer type, MaxLen must /// be of size_t type, and the return value has 'intptr_t' type. Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitStrChr - Emit a call to the strchr function to the builder, for the /// specified pointer and character. Ptr is required to be some pointer type, /// and the return value has 'i8*' type. - Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD, + Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitStrNCmp - Emit a call to the strncmp function to the builder. Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the /// specified pointer arguments. Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI, + const DataLayout *TD, const TargetLibraryInfo *TLI, StringRef Name = "strcpy"); /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the /// specified pointer arguments and length. Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI, + const DataLayout *TD, const TargetLibraryInfo *TLI, StringRef Name = "strncpy"); /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src /// are pointers. Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - IRBuilder<> &B, const TargetData *TD, + IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitMemCmp - Emit a call to the memcmp function. Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' /// (e.g. 'floor'). This function is known to take a single of type matching @@ -85,28 +85,28 @@ namespace llvm { /// EmitPutChar - Emit a call to the putchar function. This assumes that Char /// is an integer. - Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD, + Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitPutS - Emit a call to the puts function. This assumes that Str is /// some pointer. - Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD, + Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is /// an i32, and File is a pointer to FILE. Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitFPutS - Emit a call to the puts function. Str is required to be a /// pointer and File is a pointer to FILE. - Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD, + Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI); /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, - const TargetData *TD, const TargetLibraryInfo *TLI); + const DataLayout *TD, const TargetLibraryInfo *TLI); /// SimplifyFortifiedLibCalls - Helper class for folding checked library /// calls (e.g. __strcpy_chk) into their unchecked counterparts. @@ -118,7 +118,7 @@ namespace llvm { bool isString) const = 0; public: virtual ~SimplifyFortifiedLibCalls(); - bool fold(CallInst *CI, const TargetData *TD, const TargetLibraryInfo *TLI); + bool fold(CallInst *CI, const DataLayout *TD, const TargetLibraryInfo *TLI); }; } diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h new file mode 100644 index 0000000..ac8af12 --- /dev/null +++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h @@ -0,0 +1,33 @@ +//===- llvm/Transforms/Utils/BypassSlowDivision.h --------------*- 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 an optimization for div and rem on architectures that +// execute short instructions significantly faster than longer instructions. +// For example, on Intel Atom 32-bit divides are slow enough that during +// runtime it is profitable to check the value of the operands, and if they are +// positive and less than 256 use an unsigned 8-bit divide. +// +//===----------------------------------------------------------------------===// + +#ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H +#define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H + +#include "llvm/Function.h" + +namespace llvm { + +/// This optimization identifies DIV instructions that can be +/// profitably bypassed and carried out with a shorter, faster divide. +bool bypassSlowDivision(Function &F, + Function::iterator &I, + const DenseMap<unsigned int, unsigned int> &BypassWidth); + +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index b7b5d29..1780025 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -39,7 +39,7 @@ class ReturnInst; class CallSite; class Trace; class CallGraph; -class TargetData; +class DataLayout; class Loop; class LoopInfo; class AllocaInst; @@ -116,13 +116,6 @@ Function *CloneFunction(const Function *F, bool ModuleLevelChanges, ClonedCodeInfo *CodeInfo = 0); -/// CloneFunction - Version of the function that doesn't need the VMap. -/// -inline Function *CloneFunction(const Function *F, ClonedCodeInfo *CodeInfo = 0){ - ValueToValueMapTy VMap; - return CloneFunction(F, VMap, CodeInfo); -} - /// Clone OldFunc into NewFunc, transforming the old arguments into references /// to VMap values. Note that if NewFunc already has basic blocks, the ones /// cloned into it will be added to the end of the function. This function @@ -157,7 +150,7 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, SmallVectorImpl<ReturnInst*> &Returns, const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = 0, - const TargetData *TD = 0, + const DataLayout *TD = 0, Instruction *TheCall = 0); @@ -165,13 +158,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, /// InlineFunction call, and records the auxiliary results produced by it. class InlineFunctionInfo { public: - explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *td = 0) + explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *td = 0) : CG(cg), TD(td) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. CallGraph *CG; - const TargetData *TD; + const DataLayout *TD; /// StaticAllocas - InlineFunction fills this in with all static allocas that /// get copied into the caller. diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h new file mode 100644 index 0000000..cecc807 --- /dev/null +++ b/include/llvm/Transforms/Utils/IntegerDivision.h @@ -0,0 +1,48 @@ +//===- llvm/Transforms/Utils/IntegerDivision.h ------------------*- 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 an implementation of 32bit integer division for targets +// that don't have native support. It's largely derived from compiler-rt's +// implementation of __udivsi3, but hand-tuned for targets that prefer less +// control flow. +// +//===----------------------------------------------------------------------===// + +#ifndef TRANSFORMS_UTILS_INTEGERDIVISION_H +#define TRANSFORMS_UTILS_INTEGERDIVISION_H + +namespace llvm { + class BinaryOperator; +} + +namespace llvm { + + /// Generate code to calculate the remainder of two integers, replacing Rem + /// with the generated code. This currently generates code using the udiv + /// expansion, but future work includes generating more specialized code, + /// e.g. when more information about the operands are known. Currently only + /// implements 32bit scalar division (due to udiv's limitation), but future + /// work is removing this limitation. + /// + /// @brief Replace Rem with generated code. + bool expandRemainder(BinaryOperator *Rem); + + /// Generate code to divide two integers, replacing Div with the generated + /// code. This currently generates code similarly to compiler-rt's + /// implementations, but future work includes generating more specialized code + /// when more information about the operands are known. Currently only + /// implements 32bit scalar division, but future work is removing this + /// limitation. + /// + /// @brief Replace Div with generated code. + bool expandDivision(BinaryOperator* Div); + +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 495eab7..be3029e 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -18,7 +18,7 @@ #include "llvm/IRBuilder.h" #include "llvm/Operator.h" #include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/Target/TargetData.h" +#include "llvm/DataLayout.h" namespace llvm { @@ -35,7 +35,9 @@ class Pass; class PHINode; class AllocaInst; class ConstantExpr; -class TargetData; +class DataLayout; +class TargetLibraryInfo; +class TargetTransformInfo; class DIBuilder; template<typename T> class SmallVectorImpl; @@ -51,7 +53,8 @@ template<typename T> class SmallVectorImpl; /// Also calls RecursivelyDeleteTriviallyDeadInstructions() on any branch/switch /// conditions and indirectbr addresses this might make dead if /// DeleteDeadConditions is true. -bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false); +bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false, + const TargetLibraryInfo *TLI = 0); //===----------------------------------------------------------------------===// // Local dead code elimination. @@ -60,20 +63,21 @@ bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false); /// isInstructionTriviallyDead - Return true if the result produced by the /// instruction is not used, and the instruction has no side effects. /// -bool isInstructionTriviallyDead(Instruction *I); +bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0); /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. Return true if any /// instructions were deleted. -bool RecursivelyDeleteTriviallyDeadInstructions(Value *V); +bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, + const TargetLibraryInfo *TLI=0); /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively /// dead PHI node, due to being a def-use chain of single-use nodes that /// either forms a cycle or is terminated by a trivially dead instruction, /// delete it. If that makes any of its operands trivially dead, delete them /// too, recursively. Return true if a change was made. -bool RecursivelyDeleteDeadPHINode(PHINode *PN); +bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0); /// SimplifyInstructionsInBlock - Scan the specified basic block and try to @@ -81,7 +85,8 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN); /// /// This returns true if it changed the code, note that it can delete /// instructions in other blocks as well in this block. -bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); +bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0); //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring. @@ -99,7 +104,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); /// .. and delete the predecessor corresponding to the '1', this will attempt to /// recursively fold the 'and' to 0. void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, - TargetData *TD = 0); + DataLayout *TD = 0); /// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its @@ -130,7 +135,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB); /// of the CFG. It returns true if a modification was made, possibly deleting /// the basic block that was pointed to. /// -bool SimplifyCFG(BasicBlock *BB, const TargetData *TD = 0); +bool SimplifyCFG(BasicBlock *BB, const DataLayout *TD = 0, + const TargetTransformInfo *TTI = 0); /// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch, /// and if a predecessor branches to us and one of our successors, fold the @@ -158,10 +164,10 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0); /// and it is more than the alignment of the ultimate object, see if we can /// increase the alignment of the ultimate object, making this check succeed. unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, - const TargetData *TD = 0); + const DataLayout *TD = 0); /// getKnownAlignment - Try to infer an alignment for the specified pointer. -static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) { +static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) { return getOrEnforceKnownAlignment(V, 0, TD); } @@ -171,7 +177,7 @@ static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) { /// When NoAssumptions is true, no assumptions about index computation not /// overflowing is made. template<typename IRBuilderTy> -Value *EmitGEPOffset(IRBuilderTy *Builder, const TargetData &TD, User *GEP, +Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, bool NoAssumptions = false) { gep_type_iterator GTI = gep_type_begin(GEP); Type *IntPtrTy = TD.getIntPtrType(GEP->getContext()); diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 4c82149..db65a47 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -109,8 +109,8 @@ public: private: Value *GetValueAtEndOfBlockInternal(BasicBlock *BB); - void operator=(const SSAUpdater&); // DO NOT IMPLEMENT - SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT + void operator=(const SSAUpdater&) LLVM_DELETED_FUNCTION; + SSAUpdater(const SSAUpdater&) LLVM_DELETED_FUNCTION; }; /// LoadAndStorePromoter - This little helper class provides a convenient way to diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h index 2632d18..7e97e21 100644 --- a/include/llvm/Transforms/Utils/SimplifyIndVar.h +++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -21,8 +21,6 @@ namespace llvm { -extern cl::opt<bool> DisableIVRewrite; - class CastInst; class IVUsers; class Loop; diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h new file mode 100644 index 0000000..fde452b --- /dev/null +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -0,0 +1,52 @@ +//===- SimplifyLibCalls.h - Library call simplifier -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file exposes an interface to build some C language libcalls for +// optimization passes that need to call the various functions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H +#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H + +namespace llvm { + class Value; + class CallInst; + class DataLayout; + class Instruction; + class TargetLibraryInfo; + class LibCallSimplifierImpl; + + /// LibCallSimplifier - This class implements a collection of optimizations + /// that replace well formed calls to library functions with a more optimal + /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'. + class LibCallSimplifier { + /// Impl - A pointer to the actual implementation of the library call + /// simplifier. + LibCallSimplifierImpl *Impl; + public: + LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); + virtual ~LibCallSimplifier(); + + /// optimizeCall - Take the given call instruction and return a more + /// optimal value to replace the instruction with or 0 if a more + /// optimal form can't be found. Note that the returned value may + /// be equal to the instruction being optimized. In this case all + /// other instructions that use the given instruction were modified + /// and the given instruction is dead. + Value *optimizeCall(CallInst *CI); + + /// replaceAllUsesWith - This method is used when the library call + /// simplifier needs to replace instructions other than the library + /// call being modified. + virtual void replaceAllUsesWith(Instruction *I, Value *With) const; + }; +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 8594707..5390c5e 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -25,7 +25,7 @@ namespace llvm { /// ValueMapTypeRemapper - This is a class that can be implemented by clients /// to remap types when cloning constants and instructions. class ValueMapTypeRemapper { - virtual void Anchor(); // Out of line method. + virtual void anchor(); // Out of line method. public: virtual ~ValueMapTypeRemapper() {} diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h index 1e49a9c..41e53a8 100644 --- a/include/llvm/Transforms/Vectorize.h +++ b/include/llvm/Transforms/Vectorize.h @@ -107,6 +107,12 @@ BasicBlockPass * createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); //===----------------------------------------------------------------------===// +// +// LoopVectorize - Create a loop vectorization pass. +// +Pass * createLoopVectorizePass(); + +//===----------------------------------------------------------------------===// /// @brief Vectorize the BasicBlock. /// /// @param BB The BasicBlock to be vectorized diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 185258d..def4575 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -153,7 +153,7 @@ public: /// isPPC_FP128Ty - Return true if this is powerpc long double. bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; } - /// isFloatingPointTy - Return true if this is one of the five floating point + /// isFloatingPointTy - Return true if this is one of the six floating point /// types bool isFloatingPointTy() const { return getTypeID() == HalfTyID || getTypeID() == FloatTyID || @@ -167,7 +167,7 @@ public: /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP. /// - bool isFPOrFPVectorTy() const; + bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); } /// isLabelTy - Return true if this is 'label'. bool isLabelTy() const { return getTypeID() == LabelTyID; } @@ -185,7 +185,7 @@ public: /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of /// integer types. /// - bool isIntOrIntVectorTy() const; + bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); } /// isFunctionTy - True if this is an instance of FunctionType. /// @@ -203,6 +203,11 @@ public: /// bool isPointerTy() const { return getTypeID() == PointerTyID; } + /// isPtrOrPtrVectorTy - Return true if this is a pointer type or a vector of + /// pointer types. + /// + bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); } + /// isVectorTy - True if this is an instance of VectorType. /// bool isVectorTy() const { return getTypeID() == VectorTyID; } @@ -252,7 +257,7 @@ public: /// isSized - Return true if it makes sense to take the size of this type. To /// get the actual size for a particular target, it is reasonable to use the - /// TargetData subsystem to do this. + /// DataLayout subsystem to do this. /// bool isSized() const { // If it's a primitive, it is always sized. @@ -276,7 +281,7 @@ public: /// /// Note that this may not reflect the size of memory allocated for an /// instance of the type or the number of bytes that are written when an - /// instance of the type is stored to memory. The TargetData class provides + /// instance of the type is stored to memory. The DataLayout class provides /// additional query functions to provide this information. /// unsigned getPrimitiveSizeInBits() const; @@ -293,6 +298,7 @@ public: /// getScalarType - If this is a vector type, return the element type, /// otherwise return 'this'. + const Type *getScalarType() const; Type *getScalarType(); //===--------------------------------------------------------------------===// @@ -340,8 +346,10 @@ public: unsigned getVectorNumElements() const; Type *getVectorElementType() const { return getSequentialElementType(); } - unsigned getPointerAddressSpace() const; Type *getPointerElementType() const { return getSequentialElementType(); } + + /// \brief Get the address space of this pointer or pointer vector type. + unsigned getPointerAddressSpace() const; //===--------------------------------------------------------------------===// // Static members exported by the Type class itself. Useful for getting @@ -389,9 +397,6 @@ public: static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Type *) { return true; } - /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). PointerType *getPointerTo(unsigned AddrSpace = 0); diff --git a/include/llvm/Use.h b/include/llvm/Use.h index a496325..8080445 100644 --- a/include/llvm/Use.h +++ b/include/llvm/Use.h @@ -26,6 +26,7 @@ #define LLVM_USE_H #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Compiler.h" #include <cstddef> #include <iterator> @@ -66,7 +67,7 @@ public: private: /// Copy ctor - do not implement - Use(const Use &U); + Use(const Use &U) LLVM_DELETED_FUNCTION; /// Destructor - Only for zap() ~Use() { diff --git a/include/llvm/User.h b/include/llvm/User.h index 5d5460c..df303d0 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -31,8 +31,8 @@ template <class> struct OperandTraits; class User : public Value { - User(const User &); // Do not implement - void *operator new(size_t); // Do not implement + User(const User &) LLVM_DELETED_FUNCTION; + void *operator new(size_t) LLVM_DELETED_FUNCTION; template <unsigned> friend struct HungoffOperandTraits; virtual void anchor(); @@ -104,7 +104,7 @@ public: assert(i < NumOperands && "getOperandUse() out of range!"); return OperandList[i]; } - + unsigned getNumOperands() const { return NumOperands; } // --------------------------------------------------------------------------- @@ -118,6 +118,45 @@ public: inline op_iterator op_end() { return OperandList+NumOperands; } inline const_op_iterator op_end() const { return OperandList+NumOperands; } + /// Convenience iterator for directly iterating over the Values in the + /// OperandList + class value_op_iterator : public std::iterator<std::forward_iterator_tag, + Value*> { + op_iterator OI; + public: + explicit value_op_iterator(Use *U) : OI(U) {} + + bool operator==(const value_op_iterator &x) const { + return OI == x.OI; + } + bool operator!=(const value_op_iterator &x) const { + return !operator==(x); + } + + /// Iterator traversal: forward iteration only + value_op_iterator &operator++() { // Preincrement + ++OI; + return *this; + } + value_op_iterator operator++(int) { // Postincrement + value_op_iterator tmp = *this; ++*this; return tmp; + } + + /// Retrieve a pointer to the current Value. + Value *operator*() const { + return *OI; + } + + Value *operator->() const { return operator*(); } + }; + + inline value_op_iterator value_op_begin() { + return value_op_iterator(op_begin()); + } + inline value_op_iterator value_op_end() { + return value_op_iterator(op_end()); + } + // dropAllReferences() - This function is in charge of "letting go" of all // objects that this User refers to. This allows one to // 'delete' a whole class at a time, even though there may be circular @@ -137,7 +176,6 @@ public: void replaceUsesOfWith(Value *From, Value *To); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const User *) { return true; } static inline bool classof(const Value *V) { return isa<Instruction>(V) || isa<Constant>(V); } diff --git a/include/llvm/Value.h b/include/llvm/Value.h index a82ac45..5b19435 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -16,6 +16,7 @@ #include "llvm/Use.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" namespace llvm { @@ -80,8 +81,8 @@ private: friend class ValueHandleBase; ValueName *Name; - void operator=(const Value &); // Do not implement - Value(const Value &); // Do not implement + void operator=(const Value &) LLVM_DELETED_FUNCTION; + Value(const Value &) LLVM_DELETED_FUNCTION; protected: /// printCustom - Value subclasses can override this to implement custom @@ -120,7 +121,7 @@ public: /// setName() - Change the name of the value, choosing a new unique name if /// the provided name is taken. /// - /// \arg Name - The new name; or "" if the value's name should be removed. + /// \param Name The new name; or "" if the value's name should be removed. void setName(const Twine &Name); @@ -256,11 +257,6 @@ public: /// hasValueHandle - Return true if there is a value handle associated with /// this value. bool hasValueHandle() const { return HasValueHandle; } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *) { - return true; // Values are always values. - } /// stripPointerCasts - This method strips off any unneeded pointer casts and /// all-zero GEPs from the specified value, returning the original uncasted |