diff options
Diffstat (limited to 'include/llvm')
294 files changed, 8479 insertions, 3907 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 5a625a4c832f..31c6e6adbfc6 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 f30a6e3f081c..c7c8016b8339 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 cf55aadef31a..1e35d6279219 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 3e2e5f230a3a..9d6388f7ee61 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 e502ac4348d0..2dfed075dea5 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 45ba19891d4f..7bf7960c63a9 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 f60d688c0dce..ac4bdbd126c5 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 1559a35c39f9..6f17a647b63d 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 771476c30361..1d81772ee8ae 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 ba415ac2d61f..375d84abebdd 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 6ab07254a21d..cda31a261df2 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 d7c0074a9f08..20bdd903f7a5 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 8346ffabff76..4883c5ba0a6b 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 949dc44daba6..3900f96be16a 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 000000000000..6aacca5a6f0f --- /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 ee8b69f3d12f..f43aeb1bc4d9 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 6d9c30597789..05bcd40d0862 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 2eaddc2b4eea..1ae2a77e7eaf 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 fcc758b43a27..71c379bad5a4 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 a6803ee0eddf..efddd9f9b857 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 965f0deacaa2..d2f7286c2596 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 7a645e0c7241..a9cd54e13b38 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 498a0345d8bb..3bb883088c59 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 c6f0a5bf1542..8da99d1c125c 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 9fbbbe4f3b5d..6e0fd94dfe67 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 89774c3f5628..306e92832f0b 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 556963334894..063c6755c680 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 655d884e7baa..bf27c4313f82 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 cd846031c5a0..292bde0cd900 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 9c55f6b70e36..b69a964a23ba 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 845af015b052..000000000000 --- 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 7f7061ab01b9..408d70cf76f8 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 9101df8cee37..cc290d51d272 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 f7e255181e23..d23fccf3e8cc 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 ba9864a98a7e..7f5cd1718142 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 000000000000..70b3c05238c5 --- /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 674868a02633..be274afd1552 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 95626d624a13..1e606c81d9c7 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 006daa082946..c0567daa3a5e 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 fb77da7b69ea..6a9ed310375a 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 9b5e8425ad29..2889269b957a 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 03c807cf8326..4398faa20a7b 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 2fdef5f0836e..12e623ea9be4 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 000000000000..b4327eeb0b1e --- /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 a1cc196eae30..8940971558a3 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 2bf79b9c932b..9b98013a1683 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 0cba135222b9..a075db33427d 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 152e885bf667..e561e3742b64 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 df7313f18f3d..bce84be2f4fd 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 065c230fb2fd..197e94e5fd32 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 5f0aefbeb015..afc90c2f7441 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 f195d2782418..000000000000 --- 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 eeb482d82a2b..c5d7b0128e74 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 c07fbf7aa827..3bb96f96bf52 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 e674e74520d2..a842898e4100 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 7e049d633b49..a715eaeee11c 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 ff9a24790a99..5a77fcebafa0 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 a22bd12dec1e..27726f49bcce 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 000000000000..9efbafcef41c --- /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 000000000000..1be15e025da9 --- /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 6b4ac85082b0..45aab5b70d2b 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 188d11c2833c..48d7ee6b5476 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 c213ade5e8e3..235adca02175 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 ded12974face..54db7d6bcf0d 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 c3c2f4b0668c..b758eca42e78 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 e8d45f6bb8d4..a85752446bb0 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 e66075c1f235..b1c22185191d 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 223aa0063906..a9c2d743ff4a 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 d2aa1673d921..02c2a96b6c64 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 3c75e5882dbd..4fd4b5d90a9e 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 65868294403c..840f57e7526d 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 475da133f8a8..dea118f98ed2 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 a8c34cb82995..c1dc190304c2 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 4c5ee626709a..053f4eb326f9 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 170a528a5a22..a92b85939f37 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 3afe3095d4f6..436918b1eb33 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 000000000000..90ee23424498 --- /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 7cb96952aa61..7c24e36092b4 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 20e33f74f650..076f6f39fe2c 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 17a265300000..4a6b5ac19c36 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 f387bd518f17..5d0a3b4c7067 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 767b66622549..5a3fb4b1a3df 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 a3ce47c02a1a..185e414ae2cd 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 da521dbc535f..b421753dd536 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 d4bb409e0605..3bb134b8fb2a 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 c917bd8b8183..97c39458d93d 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 af4db7d6bde6..12189ceb7f16 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 d6d65a24defb..8ed215d75bcf 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 8b958e437ed3..0e4e132e40d9 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 062c7508c496..025e18a9dde0 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 27756abf3f54..7eb03a93012d 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 654361f9d423..770685358aba 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 dc5f9a6ec82d..854ba06209cd 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 f7c4e8642d53..928145d279b6 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 3e204bed15ad..d53f041128ac 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 1ac9080b75d5..ddb127120f20 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 9401ffd199d4..7afc7eb6b357 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 37d42b358382..606833cd4081 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 000000000000..a9fc8434abee --- /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 42a8aa43d982..4e86363f071a 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 cbb45a71275c..edf93d13bd1d 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 8da2045ad0be..31bd606f9320 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 a5d8b0dbd6a7..83c379b48cba 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 3fee18cc42d9..0c1fcb7eaf78 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 07b3b45873ae..7bd576494ef7 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 7dab4f948628..8f52d3bf47d2 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 bce3ec739b61..acfc07dd31a2 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 400e1f48ce54..4467b62f2370 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 2043155bc53f..30326d05df04 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 3986a8dd7da1..08d316992ec5 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 85ab47beb6b4..7e0ca1478e5f 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 000000000000..1aa405842173 --- /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 1bde94215a57..4bcd35a834c3 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 a582b0c40c8b..836b73a15a2f 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 1ccfe54d2126..619ee699430d 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 db361ee9b1bc..362e9afd225a 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 000000000000..88e6105a7de2 --- /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 eb38cd33d167..240199291ae9 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 f4b75bd1b17d..a707f887aaf4 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 041af837541c..d63675351c80 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 9729bd75eb40..f0152a4aa979 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 1e6281de9989..d3a9bbdeaeac 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 b912251239da..ca6412472991 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 5a60ba565f00..a4f8af4db028 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 e0e516d55c9a..0ddd1db6c010 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 fdd53823aa0c..7f94ef464ea4 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 2ed48a944e96..2f0780068087 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 4f94ab751cb6..24ad05f17f39 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 618220fcb010..dae03ad10095 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 cfdeb46889e5..26bd1f627526 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 929569d543d9..9f1ade86aba6 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 da5ad27b1f1c..c862c2c8bb20 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 ae8b68d0241e..8073d8f92c51 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 ca873420299c..000000000000 --- 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 eea603fcee2c..e6586e778c19 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 4c75b6ab970e..90896465018c 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 000000000000..a0a77b8ba888 --- /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 000000000000..82549add62e8 --- /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 a5c9272d3ca6..891f534862f4 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 fdd90d1d8faa..e211e9ab52a8 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 164d976588d6..d0f014733fce 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 8b969f3354c3..7f7f74b1e2da 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 99b7a73b35ac..b9d3f68642f4 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 d5b6f47f8a25..f63a16051e30 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 de97957a84c6..8c164eb91984 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 37aa18bfff73..b5e0fd4effd6 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 2529f24fe991..da17f3b80d7b 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 5512dcc9e6b6..8aa8a56bf825 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 f5187e683269..69593b48c1f1 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 1cebdd2ee642..9b2afd56e05f 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 c3503889e702..3108a8e5251c 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 d1a0feef1d5a..2e1597fe6f6b 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 fa8034e0c2ce..93b1ae1dc887 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 4375ac2a7a1b..e40e162a158d 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 e8039f23583a..d2463c0efa14 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 a8306a9e7617..5903e2e55e1f 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 697c94c094b0..806e4b37b73d 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 05e6286b7cc5..72ed1a317c55 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 9f5230b9c8fa..97aad71fd955 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 b7b2d663f4cc..5771415c81cc 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 934ef69ce3fe..057489090293 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 59545d31a655..5a8830cb66ce 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 fdb7ab23c09f..8fc437f3e691 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 abbe188fe88d..38cdc7293ba0 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 aa62eb2b16c0..00eef270d6c4 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 397a37d3ce48..e91c6a2e8ee7 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 3c4f28be7ca6..3b9420a40389 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 dbf16d870050..02383f8bc658 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 727520d4af9d..f531de8b40d9 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 949d90700e08..efaabfb9e88b 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 74e2263c731c..23e5513ae35e 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 a69075ddd002..08b00f1c478e 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 9591a0094614..14fe75fd4c31 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 9a8735f3e726..e102dfb82c4a 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 5e29ad49dd3f..0a961d6d0971 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 793c7097ba14..a71d3c321741 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 4e2aee992877..0918c93bdf3d 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 2556e5f27a30..60e7887a5396 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 46a9d71fff24..f05baeaaf689 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 3b1cdf1cd2fa..0c71ee513500 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 7da6534b6e88..21fdb6bd39b8 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 7eacde57f48f..b050c0f442b6 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 7321ca83e897..4d54465760d4 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 15eb4f4a7685..71ea8f3e901d 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 e8c3e59fac8a..230d27ef2ef0 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 31d632de60be..69213cd77d92 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 0583ce56820b..fe927555c49b 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 f5c8c09df0ea..b1cc546e1efa 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 929a2042cac6..483a80b3b595 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 8352ed183f09..f9af8bcfbf61 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 507d8827750c..57f0518cbf3a 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 2aa48b0b4724..1867a639236e 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 b40549bed6bf..0fbbb959888b 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 358b27a416cd..f3d824960c2f 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 befe812a3692..d555de3accc2 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 967420ec9f12..6f42d76ee996 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 7698441fd1cb..466de93a78b2 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 0b73f9483164..4e03daab16a3 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 f30d431b69da..c0f700d3c870 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 2ec656b0124e..1a3120ab8ba3 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 000000000000..7668bdedb7bb --- /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 1e86980cf303..b326c1135206 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 888537daa425..cd651db1f1c2 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 5c6a2d7a92f9..d14d73b1b14f 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 c50c2cc184e3..c6ad44f5f4ec 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 cf7125173ee1..d6b0ab8b3750 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 a2ad24ffead9..a644b133660f 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 c23bb6a97d2e..ad8d6d41fc4a 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 3aab4367f5bb..0c71882a77b1 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 ae1570da9c42..872c57998c4e 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 4469ae31de09..7ceeb3212119 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 506ec96930d9..a3ae78204074 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 f7ae60fef74b..2cd267116cab 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 0f07164eb8ed..bcd35e3c1e1b 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 f4a9aa0e8998..b455b28b819a 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 59812d98f589..aaa54e1090a6 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 58a18851687c..21635dcfb688 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 19e1ce89cbd5..e552315f4558 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 109b3cff85b6..6dfb4dec0e23 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 bb9e76925ed5..03039fd6459f 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 cab18dce159b..7635d5e91221 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 410edd4dc740..b52e5bc9ad33 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 e2fa8ebc56e4..8c4a760291b8 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 4005161320d6..11f9e63c9bbc 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 37890e7e4af1..025eee7f9f3e 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 06816de9716a..1f02907d9f9a 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 42ea63060f66..6abc533d28d6 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 cd13bfe6eeb0..6bb162277e2b 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 f4bedf92c441..643ee8c6c1d0 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 8d797097a840..ae1a21c7ce58 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 9b3ecda50c1e..2122e06d53fe 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 a85f23550ec8..7c9a95103158 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 0d4cb81de397..935b3075df58 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 7648e77bfbb5..ffe09b19b68b 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 d0375bedd9f2..29eafb63ca0e 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 8949a3a908fd..bcf95f2f6e66 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 531dbb216d7a..a2b4bcb9aa08 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 c65faa66219e..45f781633656 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 c0be8f130aba..ca58bfb0d73b 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 c0e842c2fe73..9017afb89038 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 94f132a05ca7..e780b50c6039 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 404cb6d6c8b6..a7418827ca32 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 61e21b86ead8..dbcf0fd11d19 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 98910eb7578f..12958fa173d0 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 2b3c329b5861..2823af33b746 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 4f5d3612da18..4385721e8206 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 5de749aeae4e..eab0f2d8057e 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 af812069b9fe..0d164f688d37 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 7b97547be52a..f9306395fce3 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 91a4eb99ff0d..ec5c88f5c8a7 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 fd5f805ffc96..2f6b7e625c3d 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 deaef4a9908a..6b51e20146d7 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 a8256b77357c..319298c13253 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 733ae626447c..000000000000 --- 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 d5e165e58b91..a50f54a436e9 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 1816445579ed..12f5c0eb306a 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 f8cebefb0eae..2160e371bda9 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 5e48629cf4d6..000000000000 --- 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 da30ab82d6c2..4570813ba6c2 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 c44b9230c0d8..ce213496935d 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 ea2874f440f7..a2c97d782e29 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 acf0419510e9..580a30fcd2d8 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 d631f58aab74..13a6fe37d7a9 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 e4bf32bd86c8..50066473b552 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 f0b181e345b7..516e0706b897 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 d1a07d1480b4..68ca5678369a 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 df4d900e4c8e..afa2ee27443a 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 4dc488dbaece..0da82fdd8971 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 3f81c06bc0b6..83bd7874df76 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 c9ca7223b5f5..96793bc036e7 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 fc23b2c6b58d..6db96d980b5e 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 000000000000..7ea2396076dc --- /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 000000000000..94db49044332 --- /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 18176e8fdbb1..fc1cd59e4e10 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 7c3cfc870156..b036040f5121 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 47ce90265bd5..3ea0a427200d 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 4b0c448acfce..8e63aaa4e873 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 3dce6fe37fd4..a5d8eed74622 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 90485eb4c69c..7d672839a630 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 8a939cc75ed3..b810f1a818c6 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 a6e41f0a27a8..ab9fc475faee 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 000000000000..ac8af122f038 --- /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 b7b5d29b320f..1780025a2797 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 000000000000..cecc8075de7d --- /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 495eab73289e..be3029e545de 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 4c821491b210..db65a47e972d 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 2632d186ff9b..7e97e218fb0b 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 000000000000..fde452bca235 --- /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 8594707a8482..5390c5e8ed47 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 1e49a9c01e6b..41e53a83e2f8 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 185258d8ff2a..def45750dd71 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 a496325c1fc6..80804459cc33 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 5d5460cd6fff..df303d0dd5f2 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 a82ac45c49ed..5b19435ebaf4 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  | 
