diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:09:07 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:09:07 +0000 |
commit | 40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (patch) | |
tree | 076117cdf3579003f07cad4cdf0593347ce58150 /include | |
parent | e7908924d847e63b02bc82bfaa1709ab9c774dcd (diff) | |
download | FreeBSD-src-40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6.zip FreeBSD-src-40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6.tar.gz |
Update LLVM to 91430.
Diffstat (limited to 'include')
62 files changed, 1233 insertions, 626 deletions
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h new file mode 100644 index 0000000..1facfa0 --- /dev/null +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -0,0 +1,91 @@ +//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_DELTAALGORITHM_H +#define LLVM_ADT_DELTAALGORITHM_H + +#include <vector> +#include <set> + +namespace llvm { + +/// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '99) +/// for minimizing arbitrary sets using a predicate function. +/// +/// The result of the algorithm is a subset of the input change set which is +/// guaranteed to satisfy the predicate, assuming that the input set did. For +/// well formed predicates, the result set is guaranteed to be such that +/// removing any single element would falsify the predicate. +/// +/// For best results the predicate function *should* (but need not) satisfy +/// certain properties, in particular: +/// (1) The predicate should return false on an empty set and true on the full +/// set. +/// (2) If the predicate returns true for a set of changes, it should return +/// true for all supersets of that set. +/// +/// It is not an error to provide a predicate that does not satisfy these +/// requirements, and the algorithm will generally produce reasonable +/// results. However, it may run substantially more tests than with a good +/// predicate. +class DeltaAlgorithm { +public: + typedef unsigned change_ty; + // FIXME: Use a decent data structure. + typedef std::set<change_ty> changeset_ty; + typedef std::vector<changeset_ty> changesetlist_ty; + +private: + /// Cache of failed test results. Successful test results are never cached + /// since we always reduce following a success. + std::set<changeset_ty> FailedTestsCache; + + /// GetTestResult - Get the test result for the \arg 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 Sinto 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 + /// 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. + /// + /// \param Res - On success, a subset of Changes which satisfies the + /// predicate. + /// \return - True on success. + bool Search(const changeset_ty &Changes, const changesetlist_ty &Sets, + changeset_ty &Res); + +protected: + /// UpdatedSearchState - Callback used when the search state changes. + virtual void UpdatedSearchState(const changeset_ty &Changes, + const changesetlist_ty &Sets) {} + + /// ExecuteOneTest - Execute a single test predicate on the change set \arg S. + virtual bool ExecuteOneTest(const changeset_ty &S) = 0; + +public: + virtual ~DeltaAlgorithm(); + + /// Run - Minimize the set \arg 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); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 8329947..8b62f2d 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -217,7 +217,8 @@ public: private: void CopyFrom(const DenseMap& other) { - if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) { + if (NumBuckets != 0 && + (!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { if (!KeyInfoT::isEqual(P->first, EmptyKey) && @@ -239,7 +240,7 @@ private: Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * other.NumBuckets)); - if (KeyInfoT::isPod() && ValueInfoT::isPod()) + if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value) memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT)); else for (size_t i = 0; i < other.NumBuckets; ++i) { diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 2f241c5..6b494ef 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -15,7 +15,7 @@ #define LLVM_ADT_DENSEMAPINFO_H #include "llvm/Support/PointerLikeTypeTraits.h" -#include <utility> +#include "llvm/Support/type_traits.h" namespace llvm { @@ -25,7 +25,6 @@ struct DenseMapInfo { //static inline T getTombstoneKey(); //static unsigned getHashValue(const T &Val); //static bool isEqual(const T &LHS, const T &RHS); - //static bool isPod() }; // Provide DenseMapInfo for all pointers. @@ -46,7 +45,6 @@ struct DenseMapInfo<T*> { (unsigned((uintptr_t)PtrVal) >> 9); } static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } - static bool isPod() { return true; } }; // Provide DenseMapInfo for chars. @@ -54,7 +52,6 @@ template<> struct DenseMapInfo<char> { static inline char getEmptyKey() { return ~0; } static inline char getTombstoneKey() { return ~0 - 1; } static unsigned getHashValue(const char& Val) { return Val * 37; } - static bool isPod() { return true; } static bool isEqual(const char &LHS, const char &RHS) { return LHS == RHS; } @@ -65,7 +62,6 @@ template<> struct DenseMapInfo<unsigned> { static inline unsigned getEmptyKey() { return ~0; } static inline unsigned getTombstoneKey() { return ~0U - 1; } static unsigned getHashValue(const unsigned& Val) { return Val * 37; } - static bool isPod() { return true; } static bool isEqual(const unsigned& LHS, const unsigned& RHS) { return LHS == RHS; } @@ -78,7 +74,6 @@ template<> struct DenseMapInfo<unsigned long> { static unsigned getHashValue(const unsigned long& Val) { return (unsigned)(Val * 37UL); } - static bool isPod() { return true; } static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { return LHS == RHS; } @@ -91,7 +86,6 @@ template<> struct DenseMapInfo<unsigned long long> { static unsigned getHashValue(const unsigned long long& Val) { return (unsigned)(Val * 37ULL); } - static bool isPod() { return true; } static bool isEqual(const unsigned long long& LHS, const unsigned long long& RHS) { return LHS == RHS; @@ -127,7 +121,6 @@ struct DenseMapInfo<std::pair<T, U> > { return (unsigned)key; } static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } - static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); } }; } // end namespace llvm diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index ce7344b..89f55ca 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -60,7 +60,7 @@ public: ValueT& operator*() { return I->first; } ValueT* operator->() { return &I->first; } - Iterator& operator++() { ++I; return *this; }; + Iterator& operator++() { ++I; return *this; } bool operator==(const Iterator& X) const { return I == X.I; } bool operator!=(const Iterator& X) const { return I != X.I; } }; @@ -73,7 +73,7 @@ public: const ValueT& operator*() { return I->first; } const ValueT* operator->() { return &I->first; } - ConstIterator& operator++() { ++I; return *this; }; + ConstIterator& operator++() { ++I; return *this; } bool operator==(const ConstIterator& X) const { return I == X.I; } bool operator!=(const ConstIterator& X) const { return I != X.I; } }; diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index 5f8cb57..7757c08 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -211,9 +211,12 @@ template<typename T> struct DenseMapInfo<ImmutableList<T> > { static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) { return X1 == X2; } - static bool isPod() { return true; } }; +template <typename T> struct isPodLike; +template <typename T> +struct isPodLike<ImmutableList<T> > { static const bool value = true; }; + } // end llvm namespace #endif diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 73ba3c7..64f4a7c 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -106,6 +106,12 @@ public: bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;} }; +template <typename T> struct isPodLike; +template<typename PointerTy, unsigned IntBits, typename IntType> +struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > { + static const bool value = true; +}; + // Provide specialization of DenseMapInfo for PointerIntPair. template<typename PointerTy, unsigned IntBits, typename IntType> struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > { @@ -125,7 +131,6 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > { return unsigned(IV) ^ unsigned(IV >> 9); } static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; } - static bool isPod() { return true; } }; // Teach SmallPtrSet that PointerIntPair is "basically a pointer". diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index f3b4533..b16649e 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -46,20 +46,17 @@ namespace std { namespace llvm { -/// SmallVectorImpl - This class consists of common code factored out of the -/// SmallVector class to reduce code duplication based on the SmallVector 'N' -/// template parameter. -template <typename T> -class SmallVectorImpl { +/// SmallVectorBase - This is all the non-templated stuff common to all +/// SmallVectors. +class SmallVectorBase { protected: - T *Begin, *End, *Capacity; + 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 either use GCC extensions, or some // number of union instances for the space, which guarantee maximal alignment. -protected: #ifdef __GNUC__ typedef char U; U FirstEl __attribute__((aligned)); @@ -72,46 +69,65 @@ protected: } FirstEl; #endif // 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); + } + + +public: + bool empty() const { return BeginX == EndX; } +}; + +/// SmallVectorImpl - This class consists of common code factored out of the +/// SmallVector class to reduce code duplication based on the SmallVector 'N' +/// template parameter. +template <typename T> +class SmallVectorImpl : public SmallVectorBase { + void setEnd(T *P) { EndX = P; } public: // Default ctor - Initialize to empty. - explicit SmallVectorImpl(unsigned N) - : Begin(reinterpret_cast<T*>(&FirstEl)), - End(reinterpret_cast<T*>(&FirstEl)), - Capacity(reinterpret_cast<T*>(&FirstEl)+N) { + explicit SmallVectorImpl(unsigned N) : SmallVectorBase(N*sizeof(T)) { } ~SmallVectorImpl() { // Destroy the constructed elements in the vector. - destroy_range(Begin, End); + destroy_range(begin(), end()); // If this wasn't grown from the inline copy, deallocate the old space. if (!isSmall()) - operator delete(Begin); + operator delete(begin()); } typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T value_type; - typedef T* iterator; - typedef const T* const_iterator; + typedef T *iterator; + typedef const T *const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - - bool empty() const { return Begin == End; } - size_type size() const { return End-Begin; } - size_type max_size() const { return size_type(-1) / sizeof(T); } + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + typedef const T *const_pointer; // forward iterator creation methods. - iterator begin() { return Begin; } - const_iterator begin() const { return Begin; } - iterator end() { return End; } - const_iterator end() const { return End; } + iterator begin() { return (iterator)BeginX; } + const_iterator begin() const { return (const_iterator)BeginX; } + iterator end() { return (iterator)EndX; } + const_iterator end() const { return (const_iterator)EndX; } +private: + iterator capacity_ptr() { return (iterator)CapacityX; } + const_iterator capacity_ptr() const { return (const_iterator)CapacityX; } +public: // reverse iterator creation methods. reverse_iterator rbegin() { return reverse_iterator(end()); } @@ -119,14 +135,25 @@ public: reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin());} - + size_type size() const { return end()-begin(); } + size_type max_size() const { return size_type(-1) / sizeof(T); } + + /// capacity - Return the total number of elements in the currently allocated + /// buffer. + size_t capacity() const { return capacity_ptr() - begin(); } + + /// data - Return a pointer to the vector's buffer, even if empty(). + pointer data() { return pointer(begin()); } + /// data - Return a pointer to the vector's buffer, even if empty(). + const_pointer data() const { return const_pointer(begin()); } + reference operator[](unsigned idx) { - assert(Begin + idx < End); - return Begin[idx]; + assert(begin() + idx < end()); + return begin()[idx]; } const_reference operator[](unsigned idx) const { - assert(Begin + idx < End); - return Begin[idx]; + assert(begin() + idx < end()); + return begin()[idx]; } reference front() { @@ -144,10 +171,10 @@ public: } void push_back(const_reference Elt) { - if (End < Capacity) { + if (EndX < CapacityX) { Retry: - new (End) T(Elt); - ++End; + new (end()) T(Elt); + setEnd(end()+1); return; } grow(); @@ -155,8 +182,8 @@ public: } void pop_back() { - --End; - End->~T(); + setEnd(end()-1); + end()->~T(); } T pop_back_val() { @@ -166,36 +193,36 @@ public: } void clear() { - destroy_range(Begin, End); - End = Begin; + destroy_range(begin(), end()); + EndX = BeginX; } void resize(unsigned N) { if (N < size()) { - destroy_range(Begin+N, End); - End = Begin+N; + destroy_range(begin()+N, end()); + setEnd(begin()+N); } else if (N > size()) { - if (unsigned(Capacity-Begin) < N) + if (capacity() < N) grow(N); - construct_range(End, Begin+N, T()); - End = Begin+N; + construct_range(end(), begin()+N, T()); + setEnd(begin()+N); } } void resize(unsigned N, const T &NV) { if (N < size()) { - destroy_range(Begin+N, End); - End = Begin+N; + destroy_range(begin()+N, end()); + setEnd(begin()+N); } else if (N > size()) { - if (unsigned(Capacity-Begin) < N) + if (capacity() < N) grow(N); - construct_range(End, Begin+N, NV); - End = Begin+N; + construct_range(end(), begin()+N, NV); + setEnd(begin()+N); } } void reserve(unsigned N) { - if (unsigned(Capacity-Begin) < N) + if (capacity() < N) grow(N); } @@ -207,38 +234,38 @@ public: void append(in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); // Grow allocated space if needed. - if (NumInputs > size_type(Capacity-End)) + if (NumInputs > size_type(capacity_ptr()-end())) grow(size()+NumInputs); // Copy the new elements over. - std::uninitialized_copy(in_start, in_end, End); - End += NumInputs; + std::uninitialized_copy(in_start, in_end, end()); + setEnd(end() + NumInputs); } /// append - Add the specified range to the end of the SmallVector. /// void append(size_type NumInputs, const T &Elt) { // Grow allocated space if needed. - if (NumInputs > size_type(Capacity-End)) + if (NumInputs > size_type(capacity_ptr()-end())) grow(size()+NumInputs); // Copy the new elements over. - std::uninitialized_fill_n(End, NumInputs, Elt); - End += NumInputs; + std::uninitialized_fill_n(end(), NumInputs, Elt); + setEnd(end() + NumInputs); } void assign(unsigned NumElts, const T &Elt) { clear(); - if (unsigned(Capacity-Begin) < NumElts) + if (capacity() < NumElts) grow(NumElts); - End = Begin+NumElts; - construct_range(Begin, End, Elt); + setEnd(begin()+NumElts); + construct_range(begin(), end(), Elt); } iterator erase(iterator I) { iterator N = I; // Shift all elts down one. - std::copy(I+1, End, I); + std::copy(I+1, end(), I); // Drop the last elt. pop_back(); return(N); @@ -247,36 +274,36 @@ public: iterator erase(iterator S, iterator E) { iterator N = S; // Shift all elts down. - iterator I = std::copy(E, End, S); + iterator I = std::copy(E, end(), S); // Drop the last elts. - destroy_range(I, End); - End = I; + destroy_range(I, end()); + setEnd(I); return(N); } iterator insert(iterator I, const T &Elt) { - if (I == End) { // Important special case for empty vector. + if (I == end()) { // Important special case for empty vector. push_back(Elt); return end()-1; } - if (End < Capacity) { + if (EndX < CapacityX) { Retry: - new (End) T(back()); - ++End; + new (end()) T(back()); + setEnd(end()+1); // Push everything else over. - std::copy_backward(I, End-1, End); + std::copy_backward(I, end()-1, end()); *I = Elt; return I; } - size_t EltNo = I-Begin; + size_t EltNo = I-begin(); grow(); - I = Begin+EltNo; + I = begin()+EltNo; goto Retry; } iterator insert(iterator I, size_type NumToInsert, const T &Elt) { - if (I == End) { // Important special case for empty vector. + if (I == end()) { // Important special case for empty vector. append(NumToInsert, Elt); return end()-1; } @@ -295,8 +322,8 @@ public: // insertion. Since we already reserved space, we know that this won't // reallocate the vector. if (size_t(end()-I) >= NumToInsert) { - T *OldEnd = End; - append(End-NumToInsert, End); + T *OldEnd = end(); + append(end()-NumToInsert, end()); // Copy the existing elements that get replaced. std::copy_backward(I, OldEnd-NumToInsert, OldEnd); @@ -309,10 +336,10 @@ public: // not inserting at the end. // Copy over the elements that we're about to overwrite. - T *OldEnd = End; - End += NumToInsert; + T *OldEnd = end(); + setEnd(end() + NumToInsert); size_t NumOverwritten = OldEnd-I; - std::uninitialized_copy(I, OldEnd, End-NumOverwritten); + std::uninitialized_copy(I, OldEnd, end()-NumOverwritten); // Replace the overwritten part. std::fill_n(I, NumOverwritten, Elt); @@ -324,7 +351,7 @@ public: template<typename ItTy> iterator insert(iterator I, ItTy From, ItTy To) { - if (I == End) { // Important special case for empty vector. + if (I == end()) { // Important special case for empty vector. append(From, To); return end()-1; } @@ -344,8 +371,8 @@ public: // insertion. Since we already reserved space, we know that this won't // reallocate the vector. if (size_t(end()-I) >= NumToInsert) { - T *OldEnd = End; - append(End-NumToInsert, End); + T *OldEnd = end(); + append(end()-NumToInsert, end()); // Copy the existing elements that get replaced. std::copy_backward(I, OldEnd-NumToInsert, OldEnd); @@ -358,10 +385,10 @@ public: // not inserting at the end. // Copy over the elements that we're about to overwrite. - T *OldEnd = End; - End += NumToInsert; + T *OldEnd = end(); + setEnd(end() + NumToInsert); size_t NumOverwritten = OldEnd-I; - std::uninitialized_copy(I, OldEnd, End-NumOverwritten); + std::uninitialized_copy(I, OldEnd, end()-NumOverwritten); // Replace the overwritten part. std::copy(From, From+NumOverwritten, I); @@ -371,25 +398,11 @@ public: return I; } - /// data - Return a pointer to the vector's buffer, even if empty(). - pointer data() { - return pointer(Begin); - } - - /// data - Return a pointer to the vector's buffer, even if empty(). - const_pointer data() const { - return const_pointer(Begin); - } - const SmallVectorImpl &operator=(const SmallVectorImpl &RHS); bool operator==(const SmallVectorImpl &RHS) const { if (size() != RHS.size()) return false; - for (T *This = Begin, *That = RHS.Begin, *E = Begin+size(); - This != E; ++This, ++That) - if (*This != *That) - return false; - return true; + return std::equal(begin(), end(), RHS.begin()); } bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); } @@ -398,10 +411,6 @@ public: RHS.begin(), RHS.end()); } - /// capacity - Return the total number of elements in the currently allocated - /// buffer. - size_t capacity() const { return Capacity - Begin; } - /// set_size - Set the array size to \arg N, which the current array must have /// enough capacity for. /// @@ -413,17 +422,10 @@ public: /// which will only be overwritten. void set_size(unsigned N) { assert(N <= capacity()); - End = Begin + N; + setEnd(begin() + N); } private: - /// isSmall - Return true if this is a smallvector which has not had dynamic - /// memory allocated for it. - bool isSmall() const { - return static_cast<const void*>(Begin) == - static_cast<const void*>(&FirstEl); - } - /// grow - double the size of the allocated memory, guaranteeing space for at /// least one more element or MinSize if specified. void grow(size_type MinSize = 0); @@ -434,6 +436,9 @@ private: } void destroy_range(T *S, T *E) { + // No need to do a destroy loop for POD's. + if (isPodLike<T>::value) return; + while (S != E) { --E; E->~T(); @@ -444,7 +449,7 @@ private: // Define this out-of-line to dissuade the C++ compiler from inlining it. template <typename T> void SmallVectorImpl<T>::grow(size_t MinSize) { - size_t CurCapacity = Capacity-Begin; + size_t CurCapacity = capacity(); size_t CurSize = size(); size_t NewCapacity = 2*CurCapacity; if (NewCapacity < MinSize) @@ -452,22 +457,22 @@ void SmallVectorImpl<T>::grow(size_t MinSize) { T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T))); // Copy the elements over. - if (is_class<T>::value) - std::uninitialized_copy(Begin, End, NewElts); + if (isPodLike<T>::value) + // Use memcpy for PODs: std::uninitialized_copy optimizes to memmove. + memcpy(NewElts, begin(), CurSize * sizeof(T)); else - // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). - memcpy(NewElts, Begin, CurSize * sizeof(T)); + std::uninitialized_copy(begin(), end(), NewElts); // Destroy the original elements. - destroy_range(Begin, End); + destroy_range(begin(), end()); // If this wasn't grown from the inline copy, deallocate the old space. if (!isSmall()) - operator delete(Begin); + operator delete(begin()); - Begin = NewElts; - End = NewElts+CurSize; - Capacity = Begin+NewCapacity; + setEnd(NewElts+CurSize); + BeginX = NewElts; + CapacityX = begin()+NewCapacity; } template <typename T> @@ -476,35 +481,35 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) { // We can only avoid copying elements if neither vector is small. if (!isSmall() && !RHS.isSmall()) { - std::swap(Begin, RHS.Begin); - std::swap(End, RHS.End); - std::swap(Capacity, RHS.Capacity); + std::swap(BeginX, RHS.BeginX); + std::swap(EndX, RHS.EndX); + std::swap(CapacityX, RHS.CapacityX); return; } - if (RHS.size() > size_type(Capacity-Begin)) + if (RHS.size() > capacity()) grow(RHS.size()); - if (size() > size_type(RHS.Capacity-RHS.begin())) + if (size() > RHS.capacity()) RHS.grow(size()); // Swap the shared elements. size_t NumShared = size(); if (NumShared > RHS.size()) NumShared = RHS.size(); for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i) - std::swap(Begin[i], RHS[i]); + std::swap((*this)[i], RHS[i]); // Copy over the extra elts. if (size() > RHS.size()) { size_t EltDiff = size() - RHS.size(); - std::uninitialized_copy(Begin+NumShared, End, RHS.End); - RHS.End += EltDiff; - destroy_range(Begin+NumShared, End); - End = Begin+NumShared; + std::uninitialized_copy(begin()+NumShared, end(), RHS.end()); + RHS.setEnd(RHS.end()+EltDiff); + destroy_range(begin()+NumShared, end()); + setEnd(begin()+NumShared); } else if (RHS.size() > size()) { size_t EltDiff = RHS.size() - size(); - std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End); - End += EltDiff; - destroy_range(RHS.Begin+NumShared, RHS.End); - RHS.End = RHS.Begin+NumShared; + std::uninitialized_copy(RHS.begin()+NumShared, RHS.end(), end()); + setEnd(end() + EltDiff); + destroy_range(RHS.begin()+NumShared, RHS.end()); + RHS.setEnd(RHS.begin()+NumShared); } } @@ -516,42 +521,42 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) { // If we already have sufficient space, assign the common elements, then // destroy any excess. - unsigned RHSSize = unsigned(RHS.size()); - unsigned CurSize = unsigned(size()); + size_t RHSSize = RHS.size(); + size_t CurSize = size(); if (CurSize >= RHSSize) { // Assign common elements. iterator NewEnd; if (RHSSize) - NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin); + NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, begin()); else - NewEnd = Begin; + NewEnd = begin(); // Destroy excess elements. - destroy_range(NewEnd, End); + destroy_range(NewEnd, end()); // Trim. - End = NewEnd; + setEnd(NewEnd); return *this; } // If we have to grow to have enough elements, destroy the current elements. // This allows us to avoid copying them during the grow. - if (unsigned(Capacity-Begin) < RHSSize) { + if (capacity() < RHSSize) { // Destroy current elements. - destroy_range(Begin, End); - End = Begin; + destroy_range(begin(), end()); + setEnd(begin()); CurSize = 0; grow(RHSSize); } else if (CurSize) { // Otherwise, use assignment for the already-constructed elements. - std::copy(RHS.Begin, RHS.Begin+CurSize, Begin); + std::copy(RHS.begin(), RHS.begin()+CurSize, begin()); } // Copy construct the new elements in place. - std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize); + std::uninitialized_copy(RHS.begin()+CurSize, RHS.end(), begin()+CurSize); // Set end. - End = Begin+RHSSize; + setEnd(begin()+RHSSize); return *this; } diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index 6562d57..7dd5647 100644 --- a/include/llvm/ADT/StringSwitch.h +++ b/include/llvm/ADT/StringSwitch.h @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===/ // // This file implements the StringSwitch template, which mimics a switch() -// statements whose cases are string literals. +// statement whose cases are string literals. // //===----------------------------------------------------------------------===/ #ifndef LLVM_ADT_STRINGSWITCH_H @@ -18,7 +18,7 @@ #include <cstring> namespace llvm { - + /// \brief A switch()-like statement whose cases are string literals. /// /// The StringSwitch class is a simple form of a switch() statement that @@ -35,48 +35,44 @@ namespace llvm { /// .Case("green", Green) /// .Case("blue", Blue) /// .Case("indigo", Indigo) -/// .Case("violet", Violet) +/// .Cases("violet", "purple", Violet) /// .Default(UnknownColor); /// \endcode -template<typename T> +template<typename T, typename R = T> class StringSwitch { /// \brief The string we are matching. StringRef Str; - - /// \brief The result of this switch statement, once known. - T Result; - - /// \brief Set true when the result of this switch is already known; in this - /// case, Result is valid. - bool ResultKnown; - + + /// \brief The pointer to the result of this switch statement, once known, + /// null before that. + const T *Result; + public: - explicit StringSwitch(StringRef Str) - : Str(Str), ResultKnown(false) { } - + explicit StringSwitch(StringRef Str) + : Str(Str), Result(0) { } + template<unsigned N> StringSwitch& Case(const char (&S)[N], const T& Value) { - if (!ResultKnown && N-1 == Str.size() && + if (!Result && N-1 == Str.size() && (std::memcmp(S, Str.data(), N-1) == 0)) { - Result = Value; - ResultKnown = true; + Result = &Value; } - + return *this; } - + template<unsigned N0, unsigned N1> StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const T& Value) { return Case(S0, Value).Case(S1, Value); } - + template<unsigned N0, unsigned N1, unsigned N2> StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const T& Value) { return Case(S0, Value).Case(S1, Value).Case(S2, Value); } - + template<unsigned N0, unsigned N1, unsigned N2, unsigned N3> StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const char (&S3)[N3], @@ -87,21 +83,21 @@ public: template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4> StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const char (&S3)[N3], - const char (&S4)[N4], const T& Value) { + const char (&S4)[N4], const T& Value) { return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value) .Case(S4, Value); } - - T Default(const T& Value) { - if (ResultKnown) - return Result; - + + R Default(const T& Value) const { + if (Result) + return *Result; + return Value; } - - operator T() { - assert(ResultKnown && "Fell off the end of a string-switch"); - return Result; + + operator R() const { + assert(Result && "Fell off the end of a string-switch"); + return *Result; } }; diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h index b043c38..6f57fe8 100644 --- a/include/llvm/ADT/ValueMap.h +++ b/include/llvm/ADT/ValueMap.h @@ -250,6 +250,12 @@ public: } }; + +template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> +struct isPodLike<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { + static const bool value = true; +}; + template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH; @@ -267,7 +273,6 @@ struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { static bool isEqual(const VH &LHS, const VH &RHS) { return LHS == RHS; } - static bool isPod() { return false; } }; diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index b3824a2..e4d26dd 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -643,7 +643,7 @@ struct ilist : public iplist<NodeTy> { // Main implementation here - Insert for a node passed by value... iterator insert(iterator where, const NodeTy &val) { - return insert(where, createNode(val)); + return insert(where, this->createNode(val)); } diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 42a377e..09f12ad 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -259,11 +259,9 @@ class AliasSetTracker { ASTCallbackVH(Value *V, AliasSetTracker *AST = 0); ASTCallbackVH &operator=(Value *V); }; - /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that ASTCallbackVH - /// is not a POD (it needs its destructor called). - struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> { - static bool isPod() { return false; } - }; + /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to + /// compare and hash the value handle. + struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {}; AliasAnalysis &AA; ilist<AliasSet> AliasSets; diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 866ed8a..232804e 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -197,7 +197,8 @@ namespace llvm { FlagProtected = 1 << 1, FlagFwdDecl = 1 << 2, FlagAppleBlock = 1 << 3, - FlagBlockByrefStruct = 1 << 4 + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5 }; protected: @@ -242,6 +243,9 @@ namespace llvm { bool isBlockByrefStruct() const { return (getFlags() & FlagBlockByrefStruct) != 0; } + bool isVirtual() const { + return (getFlags() & FlagVirtual) != 0; + } /// dump - print type. void dump() const; @@ -366,6 +370,24 @@ namespace llvm { /// compile unit, like 'static' in C. unsigned isLocalToUnit() const { return getUnsignedField(9); } unsigned isDefinition() const { return getUnsignedField(10); } + + unsigned getVirtuality() const { + if (DbgNode->getNumElements() < 14) + return 0; + return getUnsignedField(11); + } + + unsigned getVirtualIndex() const { + if (DbgNode->getNumElements() < 14) + return 0; + return getUnsignedField(12); + } + + DICompositeType getContainingType() const { + assert (DbgNode->getNumElements() >= 14 && "Invalid type!"); + return getFieldAs<DICompositeType>(13); + } + StringRef getFilename() const { return getCompileUnit().getFilename();} StringRef getDirectory() const { return getCompileUnit().getDirectory();} @@ -470,6 +492,7 @@ namespace llvm { const Type *EmptyStructPtr; // "{}*". Function *DeclareFn; // llvm.dbg.declare + Function *ValueFn; // llvm.dbg.value DIFactory(const DIFactory &); // DO NOT IMPLEMENT void operator=(const DIFactory&); // DO NOT IMPLEMENT @@ -565,7 +588,14 @@ namespace llvm { StringRef LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, - bool isDefinition); + bool isDefinition, + unsigned VK = 0, + unsigned VIndex = 0, + DIType = DIType()); + + /// CreateSubprogramDefinition - Create new subprogram descriptor for the + /// given declaration. + DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration); /// CreateGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable @@ -610,6 +640,13 @@ namespace llvm { Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, Instruction *InsertBefore); + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, BasicBlock *InsertAtEnd); + + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); }; diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 22fbb35..fcd9caa 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -175,11 +175,11 @@ class IVUsers : public LoopPass { ScalarEvolution *SE; SmallPtrSet<Instruction*,16> Processed; -public: /// IVUses - A list of all tracked IV uses of induction variable expressions /// we are interested in. ilist<IVUsersOfOneStride> IVUses; +public: /// IVUsesByStride - A mapping from the strides in StrideOrder to the /// uses in IVUses. std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride; diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h index 1d386ba..a1a5637 100644 --- a/include/llvm/Analysis/LoopDependenceAnalysis.h +++ b/include/llvm/Analysis/LoopDependenceAnalysis.h @@ -67,17 +67,17 @@ class LoopDependenceAnalysis : public LoopPass { /// 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 a given SCEV is variant - /// in. + /// 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. + /// 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 + /// 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. + /// in the loop nest and X is a induction variable in the loop nest. bool isAffine(const SCEV*) const; /// TODO: doc @@ -93,8 +93,8 @@ public: static char ID; // Class identification, replacement for typeinfo LoopDependenceAnalysis() : LoopPass(&ID) {} - /// isDependencePair - Check wether two values can possibly give rise to a - /// data dependence: that is the case if both are instructions accessing + /// 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; diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 9969d99..2294e53 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -568,7 +568,7 @@ public: /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. - /// This assumes that loop is in canonical form. + /// This assumes that loop exits are in canonical form. /// void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const; @@ -976,13 +976,6 @@ public: void removeBlock(BasicBlock *BB) { LI.removeBlock(BB); } - - static bool isNotAlreadyContainedIn(const Loop *SubLoop, - const Loop *ParentLoop) { - return - LoopInfoBase<BasicBlock, Loop>::isNotAlreadyContainedIn(SubLoop, - ParentLoop); - } }; diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 2eb329f..2dceccb 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -52,7 +52,7 @@ public: // LPPassManger as expected. void preparePassManager(PMStack &PMS); - /// Assign pass manager to manager this pass + /// Assign pass manager to manage this pass virtual void assignPassManager(PMStack &PMS, PassManagerType PMT = PMT_LoopPassManager); @@ -73,7 +73,7 @@ public: /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block. virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {} - /// deletekAnalysisValue - Delete analysis info associated with value V. + /// deleteAnalysisValue - Delete analysis info associated with value V. virtual void deleteAnalysisValue(Value *V, Loop *L) {} }; diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 6b300fd..c04631b 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -16,6 +16,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Pass.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" @@ -31,6 +32,7 @@ namespace llvm { class MemoryDependenceAnalysis; class PredIteratorCache; class DominatorTree; + class PHITransAddr; /// MemDepResult - A memory dependence query can return one of three different /// answers, described below. @@ -60,9 +62,9 @@ namespace llvm { /// this case, the load is loading an undef value or a store is the /// first store to (that part of) the allocation. /// 3. Dependence queries on calls return Def only when they are - /// readonly calls with identical callees and no intervening - /// clobbers. No validation is done that the operands to the calls - /// are the same. + /// readonly calls or memory use intrinsics with identical callees + /// and no intervening clobbers. No validation is done that the + /// operands to the calls are the same. Def, /// NonLocal - This marker indicates that the query has no dependency in @@ -130,6 +132,45 @@ namespace llvm { } }; + /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache, and an + /// entry in the results set for a non-local query. For each BasicBlock (the + /// BB entry) it keeps a MemDepResult and the (potentially phi translated) + /// address that was live in the block. + class NonLocalDepEntry { + BasicBlock *BB; + MemDepResult Result; + WeakVH Address; + public: + NonLocalDepEntry(BasicBlock *bb, MemDepResult result, Value *address) + : BB(bb), Result(result), Address(address) {} + + // This is used for searches. + NonLocalDepEntry(BasicBlock *bb) : BB(bb) {} + + // BB is the sort key, it can't be changed. + BasicBlock *getBB() const { return BB; } + + void setResult(const MemDepResult &R, Value *Addr) { + Result = R; + Address = Addr; + } + + const MemDepResult &getResult() const { return Result; } + + /// getAddress - Return the address of this pointer in this block. This can + /// be different than the address queried for the non-local result because + /// of phi translation. This returns null if the address was not available + /// in a block (i.e. because phi translation failed) or if this is a cached + /// result and that address was deleted. + /// + /// The address is always null for a non-local 'call' dependence. + Value *getAddress() const { return Address; } + + bool operator<(const NonLocalDepEntry &RHS) const { + return BB < RHS.BB; + } + }; + /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, @@ -151,7 +192,6 @@ namespace llvm { LocalDepMapType LocalDeps; public: - typedef std::pair<BasicBlock*, MemDepResult> NonLocalDepEntry; typedef std::vector<NonLocalDepEntry> NonLocalDepInfo; private: /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if @@ -245,29 +285,6 @@ namespace llvm { BasicBlock *BB, SmallVectorImpl<NonLocalDepEntry> &Result); - /// GetPHITranslatedValue - Find an available version of the specified value - /// PHI translated across the specified edge. If MemDep isn't able to - /// satisfy this request, it returns null. - Value *GetPHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD) const; - - /// GetAvailablePHITranslatedValue - Return the value computed by - /// PHITranslatePointer if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const; - - /// InsertPHITranslatedPointer - Insert a computation of the PHI translated - /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB - /// block. All newly created instructions are added to the NewInsts list. - Value *InsertPHITranslatedPointer(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl<Instruction*> &NewInsts) const; - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); @@ -288,7 +305,7 @@ namespace llvm { MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB); - bool getNonLocalPointerDepFromBB(Value *Pointer, uint64_t Size, + bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size, bool isLoad, BasicBlock *BB, SmallVectorImpl<NonLocalDepEntry> &Result, DenseMap<BasicBlock*, Value*> &Visited, diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h new file mode 100644 index 0000000..b612316 --- /dev/null +++ b/include/llvm/Analysis/PHITransAddr.h @@ -0,0 +1,121 @@ +//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the PHITransAddr class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PHITRANSADDR_H +#define LLVM_ANALYSIS_PHITRANSADDR_H + +#include "llvm/Instruction.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + class DominatorTree; + class TargetData; + +/// PHITransAddr - An address value which tracks and handles phi translation. +/// As we walk "up" the CFG through predecessors, we need to ensure that the +/// address we're tracking is kept up to date. For example, if we're analyzing +/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI +/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an +/// incorrect pointer in the predecessor block. +/// +/// This is designed to be a relatively small object that lives on the stack and +/// is copyable. +/// +class PHITransAddr { + /// Addr - The actual address we're analyzing. + Value *Addr; + + /// TD - The target data we are playing with if known, otherwise null. + const TargetData *TD; + + /// InstInputs - The inputs for our symbolic address. + SmallVector<Instruction*, 4> InstInputs; +public: + PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) { + // If the address is an instruction, the whole thing is considered an input. + if (Instruction *I = dyn_cast<Instruction>(Addr)) + InstInputs.push_back(I); + } + + Value *getAddr() const { return Addr; } + + /// NeedsPHITranslationFromBlock - Return true if moving from the specified + /// BasicBlock to its predecessors requires PHI translation. + bool NeedsPHITranslationFromBlock(BasicBlock *BB) const { + // We do need translation if one of our input instructions is defined in + // this block. + for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) + if (InstInputs[i]->getParent() == BB) + return true; + return false; + } + + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true + /// if we have some hope of doing it. This should be used as a filter to + /// avoid calling PHITranslateValue in hopeless situations. + bool IsPotentiallyPHITranslatable() const; + + /// PHITranslateValue - PHI translate the current address up the CFG from + /// CurBB to Pred, updating our state the reflect any needed changes. This + /// returns true on failure and sets Addr to null. + bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); + + /// PHITranslateWithInsertion - PHI translate this value into the specified + /// predecessor block, inserting a computation of the value if it is + /// unavailable. + /// + /// All newly created instructions are added to the NewInsts list. This + /// returns null on failure. + /// + Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl<Instruction*> &NewInsts); + + void dump() const; + + /// Verify - Check internal consistency of this data structure. If the + /// structure is valid, it returns true. If invalid, it prints errors and + /// returns false. + bool Verify() const; +private: + Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); + + + /// GetAvailablePHITranslatedSubExpr - Return the value computed by + /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. + Value *GetAvailablePHITranslatedSubExpr(Value *V, + BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT) const; + + /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated + /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB + /// block. All newly created instructions are added to the NewInsts list. + /// This returns null on failure. + /// + Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl<Instruction*> &NewInsts); + + /// AddAsInput - If the specified value is an instruction, add it as an input. + Value *AddAsInput(Value *V) { + // If V is an instruction, it is now an input. + if (Instruction *VI = dyn_cast<Instruction>(V)) + InstInputs.push_back(VI); + return V; + } + +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index b222321..2f39c6a 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -92,6 +92,7 @@ namespace llvm { // file. // ModulePass *createProfileLoaderPass(); + extern const PassInfo *ProfileLoaderPassID; //===--------------------------------------------------------------------===// // diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h index 2a80f3d..80ba6d8 100644 --- a/include/llvm/Analysis/ProfileInfo.h +++ b/include/llvm/Analysis/ProfileInfo.h @@ -21,116 +21,228 @@ #ifndef LLVM_ANALYSIS_PROFILEINFO_H #define LLVM_ANALYSIS_PROFILEINFO_H -#include "llvm/BasicBlock.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <string> #include <map> +#include <set> namespace llvm { - class Function; class Pass; class raw_ostream; + class BasicBlock; + class Function; + class MachineBasicBlock; + class MachineFunction; + + // Helper for dumping edges to errs(). + raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E); + raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E); + + raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB); + raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB); + + raw_ostream& operator<<(raw_ostream &O, const Function *F); + raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF); + /// ProfileInfo Class - This class holds and maintains profiling /// information for some unit of code. - class ProfileInfo { + template<class FType, class BType> + class ProfileInfoT { public: // Types for handling profiling information. - typedef std::pair<const BasicBlock*, const BasicBlock*> Edge; + typedef std::pair<const BType*, const BType*> Edge; typedef std::pair<Edge, double> EdgeWeight; typedef std::map<Edge, double> EdgeWeights; - typedef std::map<const BasicBlock*, double> BlockCounts; + typedef std::map<const BType*, double> BlockCounts; + typedef std::map<const BType*, const BType*> Path; protected: // EdgeInformation - 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. - std::map<const Function*, EdgeWeights> EdgeInformation; + std::map<const FType*, EdgeWeights> EdgeInformation; // BlockInformation - Count the number of times a block is executed. - std::map<const Function*, BlockCounts> BlockInformation; + std::map<const FType*, BlockCounts> BlockInformation; // FunctionInformation - Count the number of times a function is executed. - std::map<const Function*, double> FunctionInformation; + std::map<const FType*, double> FunctionInformation; + + ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile; public: static char ID; // Class identification, replacement for typeinfo - virtual ~ProfileInfo(); // We want to be subclassed + ProfileInfoT(); + ~ProfileInfoT(); // We want to be subclassed // MissingValue - The value that is returned for execution counts in case // no value is available. static const double MissingValue; // getFunction() - Returns the Function for an Edge, checking for validity. - static const Function* getFunction(Edge e) { + static const FType* getFunction(Edge e) { if (e.first) { return e.first->getParent(); } else if (e.second) { return e.second->getParent(); } assert(0 && "Invalid ProfileInfo::Edge"); - return (const Function*)0; + return (const FType*)0; } // getEdge() - Creates an Edge from two BasicBlocks. - static Edge getEdge(const BasicBlock *Src, const BasicBlock *Dest) { + static Edge getEdge(const BType *Src, const BType *Dest) { return std::make_pair(Src, Dest); } //===------------------------------------------------------------------===// /// Profile Information Queries /// - double getExecutionCount(const Function *F); + double getExecutionCount(const FType *F); + + double getExecutionCount(const BType *BB); - double getExecutionCount(const BasicBlock *BB); + void setExecutionCount(const BType *BB, double w); + + void addExecutionCount(const BType *BB, double w); double getEdgeWeight(Edge e) const { - std::map<const Function*, EdgeWeights>::const_iterator J = + typename std::map<const FType*, EdgeWeights>::const_iterator J = EdgeInformation.find(getFunction(e)); if (J == EdgeInformation.end()) return MissingValue; - EdgeWeights::const_iterator I = J->second.find(e); + typename EdgeWeights::const_iterator I = J->second.find(e); if (I == J->second.end()) return MissingValue; return I->second; } - EdgeWeights &getEdgeWeights (const Function *F) { + void setEdgeWeight(Edge e, double w) { + DEBUG_WITH_TYPE("profile-info", + errs() << "Creating Edge " << e + << " (weight: " << format("%.20g",w) << ")\n"); + EdgeInformation[getFunction(e)][e] = w; + } + + void addEdgeWeight(Edge e, double w); + + EdgeWeights &getEdgeWeights (const FType *F) { return EdgeInformation[F]; } //===------------------------------------------------------------------===// /// Analysis Update Methods /// - void removeBlock(const BasicBlock *BB) { - std::map<const Function*, BlockCounts>::iterator J = - BlockInformation.find(BB->getParent()); - if (J == BlockInformation.end()) return; - - J->second.erase(BB); + void removeBlock(const BType *BB); + + void removeEdge(Edge e); + + void replaceEdge(const Edge &, const Edge &); + + enum GetPathMode { + GetPathToExit = 1, + GetPathToValue = 2, + GetPathToDest = 4, + GetPathWithNewEdges = 8 + }; + + const BType *GetPath(const BType *Src, const BType *Dest, + Path &P, unsigned Mode); + + void divertFlow(const Edge &, const Edge &); + + void splitEdge(const BType *FirstBB, const BType *SecondBB, + const BType *NewBB, bool MergeIdenticalEdges = false); + + void splitBlock(const BType *Old, const BType* New); + + void splitBlock(const BType *BB, const BType* NewBB, + BType *const *Preds, unsigned NumPreds); + + void replaceAllUses(const BType *RmBB, const BType *DestBB); + + void transfer(const FType *Old, const FType *New); + + void repair(const FType *F); + + void dump(FType *F = 0, bool real = true) { + errs() << "**** This is ProfileInfo " << this << " speaking:\n"; + if (!real) { + typename std::set<const FType*> Functions; + + errs() << "Functions: \n"; + if (F) { + errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + Functions.insert(F); + } else { + for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(), + fe = FunctionInformation.end(); fi != fe; ++fi) { + errs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n"; + Functions.insert(fi->first); + } + } + + for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + const FType *F = *FI; + typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F); + errs() << "BasicBlocks for Function " << F << ":\n"; + for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) { + errs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n"; + } + } + + for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI); + errs() << "Edges for Function " << ei->first << ":\n"; + for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end(); + ewi != ewe; ++ewi) { + errs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n"; + } + } + } else { + assert(F && "No function given, this is not supported!"); + errs() << "Functions: \n"; + errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + + errs() << "BasicBlocks for Function " << F << ":\n"; + for (typename FType::const_iterator BI = F->begin(), BE = F->end(); + BI != BE; ++BI) { + const BType *BB = &(*BI); + errs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n"; + } + } + errs() << "**** ProfileInfo " << this << ", over and out.\n"; } - void removeEdge(Edge e) { - std::map<const Function*, EdgeWeights>::iterator J = - EdgeInformation.find(getFunction(e)); - if (J == EdgeInformation.end()) return; + bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false); - J->second.erase(e); - } + bool EstimateMissingEdges(const BType *BB); - void splitEdge(const BasicBlock *FirstBB, const BasicBlock *SecondBB, - const BasicBlock *NewBB, bool MergeIdenticalEdges = false); + ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() { + if (MachineProfile == 0) + MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>(); + return MachineProfile; + } - void replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB); + bool hasMI() const { + return (MachineProfile != 0); + } }; + typedef ProfileInfoT<Function, BasicBlock> ProfileInfo; + typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo; + /// createProfileLoaderPass - This function returns a Pass that loads the /// profiling information for the module from the specified filename, making /// it available to the optimizers. Pass *createProfileLoaderPass(const std::string &Filename); - raw_ostream& operator<<(raw_ostream &O, ProfileInfo::Edge E); - } // End llvm namespace #endif diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index 3a846c2..ca54f48 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -51,6 +51,10 @@ public: /// in its containing function. bool hasByValAttr() const; + /// hasNestAttr - Return true if this argument has the nest attribute on + /// it in its containing function. + bool hasNestAttr() const; + /// hasNoAliasAttr - Return true if this argument has the noalias attribute on /// it in its containing function. bool hasNoAliasAttr() const; diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h index 90a5141..3266038 100644 --- a/include/llvm/Bitcode/Deserialize.h +++ b/include/llvm/Bitcode/Deserialize.h @@ -25,53 +25,52 @@ namespace llvm { +struct BPNode { + BPNode* Next; + uintptr_t& PtrRef; + + BPNode(BPNode* n, uintptr_t& pref) + : Next(n), PtrRef(pref) { + PtrRef = 0; + } +}; + +struct BPEntry { + union { BPNode* Head; void* Ptr; }; + BPEntry() : Head(NULL) {} + void SetPtr(BPNode*& FreeList, void* P); +}; + +class BPKey { + unsigned Raw; +public: + BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); } + BPKey(unsigned code, unsigned) : Raw(code) {} + + void MarkFinal() { Raw |= 0x1; } + bool hasFinalPtr() const { return Raw & 0x1 ? true : false; } + SerializedPtrID getID() const { return Raw >> 1; } + + static inline BPKey getEmptyKey() { return BPKey(0,0); } + static inline BPKey getTombstoneKey() { return BPKey(1,0); } + static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; } + + static bool isEqual(const BPKey& K1, const BPKey& K2) { + return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true; + } +}; + +template <> +struct isPodLike<BPKey> { static const bool value = true; }; +template <> +struct isPodLike<BPEntry> { static const bool value = true; }; + class Deserializer { //===----------------------------------------------------------===// // Internal type definitions. //===----------------------------------------------------------===// - struct BPNode { - BPNode* Next; - uintptr_t& PtrRef; - - BPNode(BPNode* n, uintptr_t& pref) - : Next(n), PtrRef(pref) { - PtrRef = 0; - } - }; - - struct BPEntry { - union { BPNode* Head; void* Ptr; }; - - BPEntry() : Head(NULL) {} - - static inline bool isPod() { return true; } - - void SetPtr(BPNode*& FreeList, void* P); - }; - - class BPKey { - unsigned Raw; - - public: - BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); } - BPKey(unsigned code, unsigned) : Raw(code) {} - - void MarkFinal() { Raw |= 0x1; } - bool hasFinalPtr() const { return Raw & 0x1 ? true : false; } - SerializedPtrID getID() const { return Raw >> 1; } - - static inline BPKey getEmptyKey() { return BPKey(0,0); } - static inline BPKey getTombstoneKey() { return BPKey(1,0); } - static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; } - - static bool isEqual(const BPKey& K1, const BPKey& K2) { - return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true; - } - - static bool isPod() { return true; } - }; typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy; diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h index 318ea28..c54527c 100644 --- a/include/llvm/CallingConv.h +++ b/include/llvm/CallingConv.h @@ -68,7 +68,10 @@ namespace CallingConv { ARM_AAPCS = 67, /// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI. - ARM_AAPCS_VFP = 68 + ARM_AAPCS_VFP = 68, + + /// MSP430_INTR - Calling convention used for MSP430 interrupt routines. + MSP430_INTR = 69 }; } // End CallingConv namespace diff --git a/include/llvm/CodeGen/BreakCriticalMachineEdge.h b/include/llvm/CodeGen/BreakCriticalMachineEdge.h deleted file mode 100644 index 4861297..0000000 --- a/include/llvm/CodeGen/BreakCriticalMachineEdge.h +++ /dev/null @@ -1,108 +0,0 @@ -//===--------- BreakCriticalMachineEdge.h - Break critical edges ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// -// -// Helper function to break a critical machine edge. -// -//===---------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H -#define LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H - -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -MachineBasicBlock* SplitCriticalMachineEdge(MachineBasicBlock* src, - MachineBasicBlock* dst) { - MachineFunction &MF = *src->getParent(); - const BasicBlock* srcBB = src->getBasicBlock(); - - MachineBasicBlock* crit_mbb = MF.CreateMachineBasicBlock(srcBB); - - // modify the llvm control flow graph - src->removeSuccessor(dst); - src->addSuccessor(crit_mbb); - crit_mbb->addSuccessor(dst); - - // insert the new block into the machine function. - MF.push_back(crit_mbb); - - // insert a unconditional branch linking the new block to dst - const TargetMachine& TM = MF.getTarget(); - const TargetInstrInfo* TII = TM.getInstrInfo(); - std::vector<MachineOperand> emptyConditions; - TII->InsertBranch(*crit_mbb, dst, (MachineBasicBlock*)0, - emptyConditions); - - // modify every branch in src that points to dst to point to the new - // machine basic block instead: - MachineBasicBlock::iterator mii = src->end(); - bool found_branch = false; - while (mii != src->begin()) { - mii--; - // if there are no more branches, finish the loop - if (!mii->getDesc().isTerminator()) { - break; - } - - // Scan the operands of this branch, replacing any uses of dst with - // crit_mbb. - for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { - MachineOperand & mo = mii->getOperand(i); - if (mo.isMBB() && mo.getMBB() == dst) { - found_branch = true; - mo.setMBB(crit_mbb); - } - } - } - - // TODO: This is tentative. It may be necessary to fix this code. Maybe - // I am inserting too many gotos, but I am trusting that the asm printer - // will optimize the unnecessary gotos. - if(!found_branch) { - TII->InsertBranch(*src, crit_mbb, (MachineBasicBlock*)0, - emptyConditions); - } - - /// Change all the phi functions in dst, so that the incoming block be - /// crit_mbb, instead of src - for(mii = dst->begin(); mii != dst->end(); mii++) { - /// the first instructions are always phi functions. - if(mii->getOpcode() != TargetInstrInfo::PHI) - break; - - // Find the operands corresponding to the source block - std::vector<unsigned> toRemove; - unsigned reg = 0; - for (unsigned u = 0; u != mii->getNumOperands(); ++u) - if (mii->getOperand(u).isMBB() && - mii->getOperand(u).getMBB() == src) { - reg = mii->getOperand(u-1).getReg(); - toRemove.push_back(u-1); - } - // Remove all uses of this MBB - for (std::vector<unsigned>::reverse_iterator I = toRemove.rbegin(), - E = toRemove.rend(); I != E; ++I) { - mii->RemoveOperand(*I+1); - mii->RemoveOperand(*I); - } - - // Add a single use corresponding to the new MBB - mii->addOperand(MachineOperand::CreateReg(reg, false)); - mii->addOperand(MachineOperand::CreateMBB(crit_mbb)); - } - - return crit_mbb; -} - -} - -#endif diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h new file mode 100644 index 0000000..2fc03bd --- /dev/null +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -0,0 +1,39 @@ +//===---------------- lib/CodeGen/CalcSpillWeights.h ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H +#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H + +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + + class LiveInterval; + + /// CalculateSpillWeights - Compute spill weights for all virtual register + /// live intervals. + class CalculateSpillWeights : public MachineFunctionPass { + public: + static char ID; + + CalculateSpillWeights() : MachineFunctionPass(&ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &au) const; + + virtual bool runOnMachineFunction(MachineFunction &fn); + + private: + /// Returns true if the given live interval is zero length. + bool isZeroLengthInterval(LiveInterval *li) const; + }; + +} + +#endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 624f18a..7233f3f 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -93,7 +93,7 @@ void SelectRoot(SelectionDAG &DAG) { // a reference to the root node, preventing it from being deleted, // and tracking any changes of the root. HandleSDNode Dummy(CurDAG->getRoot()); - ISelPosition = next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode())); + ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode())); // The AllNodes list is now topological-sorted. Visit the // nodes by starting at the end of the list (the root of the @@ -110,8 +110,7 @@ void SelectRoot(SelectionDAG &DAG) { DAG.setSubgraphColor(Node, "red"); #endif SDNode *ResNode = Select(SDValue(Node, 0)); - // If node should not be replaced, - // continue with the next one. + // If node should not be replaced, continue with the next one. if (ResNode == Node) continue; // Replace node. diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 1efd1e0..806952a 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -98,14 +98,6 @@ public: /// bool SelectOperator(User *I, unsigned Opcode); - /// TargetSelectInstruction - This method is called by target-independent - /// code when the normal FastISel process fails to select an instruction. - /// This gives targets a chance to emit code for anything that doesn't - /// fit into FastISel's framework. It returns true if it was successful. - /// - virtual bool - TargetSelectInstruction(Instruction *I) = 0; - /// getRegForValue - Create a virtual register and arrange for it to /// be assigned the value for the given LLVM value. unsigned getRegForValue(Value *V); @@ -134,6 +126,14 @@ protected: #endif ); + /// TargetSelectInstruction - This method is called by target-independent + /// code when the normal FastISel process fails to select an instruction. + /// This gives targets a chance to emit code for anything that doesn't + /// fit into FastISel's framework. It returns true if it was successful. + /// + virtual bool + TargetSelectInstruction(Instruction *I) = 0; + /// FastEmit_r - This method is called by target-independent code /// to request that an instruction with the given type and opcode /// be emitted. diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 4d2d0ee..5608c99 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -19,6 +19,7 @@ #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/GCs.h" #include "llvm/Target/TargetMachine.h" +#include <cstdlib> namespace { struct ForceCodegenLinking { diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 7a02d0f..d7ff8da 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -112,10 +112,13 @@ namespace llvm { return (unsigned)(IntervalPercentage * indexes_->getFunctionSize()); } - /// conflictsWithPhysRegDef - Returns true if the specified register - /// is defined during the duration of the specified interval. - bool conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm, - unsigned reg); + /// conflictsWithPhysReg - Returns true if the specified register is used or + /// defined during the duration of the specified interval. Copies to and + /// from li.reg are allowed. This method is only able to analyze simple + /// ranges that stay within a single basic block. Anything else is + /// considered a conflict. + bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm, + unsigned reg); /// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except /// it can check use as well. @@ -186,6 +189,10 @@ namespace llvm { return indexes_->getMBBFromIndex(index); } + SlotIndex getMBBTerminatorGap(const MachineBasicBlock *mbb) { + return indexes_->getTerminatorGap(mbb); + } + SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) { return indexes_->insertMachineInstrInMaps(MI); } diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 39a4b89..a7bf600 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -283,6 +283,11 @@ public: return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI); } + /// isLiveOut - Determine if Reg is live out from MBB, when not considering + /// PHI nodes. This means that Reg is either killed by a successor block or + /// passed through one. + bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB); + /// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All /// variables that are live out of DomBB and live into SuccBB will be marked /// as passing live through BB. This method assumes that the machine code is diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index bed82af..968e4ea 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -327,7 +327,20 @@ public: /// setMaxAlignment - Set the preferred alignment. /// void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } - + + /// calculateMaxStackAlignment() - If there is a local object which requires + /// greater alignment than the current max alignment, adjust accordingly. + void calculateMaxStackAlignment() { + for (int i = getObjectIndexBegin(), + e = getObjectIndexEnd(); i != e; ++i) { + if (isDeadObjectIndex(i)) + continue; + + unsigned Align = getObjectAlignment(i); + MaxAlignment = std::max(MaxAlignment, Align); + } + } + /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index c620449..87b67d6 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -320,6 +320,11 @@ public: /// loads the instruction does are invariant (if it does multiple loads). bool isInvariantLoad(AliasAnalysis *AA) const; + /// isConstantValuePHI - If the specified instruction is a PHI that always + /// merges together the same virtual register, return the register, otherwise + /// return 0. + unsigned isConstantValuePHI() const; + // // Debugging support // diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h new file mode 100644 index 0000000..ab663fe --- /dev/null +++ b/include/llvm/CodeGen/MachineSSAUpdater.h @@ -0,0 +1,115 @@ +//===-- MachineSSAUpdater.h - Unstructured SSA Update Tool ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MachineSSAUpdater class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H +#define LLVM_CODEGEN_MACHINESSAUPDATER_H + +namespace llvm { + class MachineBasicBlock; + class MachineFunction; + class MachineInstr; + class MachineOperand; + class MachineRegisterInfo; + class TargetInstrInfo; + class TargetRegisterClass; + template<typename T> class SmallVectorImpl; + +/// MachineSSAUpdater - This class updates SSA form for a set of virtual +/// registers defined in multiple blocks. This is used when code duplication +/// or another unstructured transformation wants to rewrite a set of uses of one +/// vreg with uses of a set of vregs. +class MachineSSAUpdater { + /// AvailableVals - This keeps track of which value to use on a per-block + /// basis. When we insert PHI nodes, we keep track of them here. + //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy; + void *AV; + + /// IncomingPredInfo - We use this as scratch space when doing our recursive + /// walk. This should only be used in GetValueInBlockInternal, normally it + /// should be empty. + //std::vector<std::pair<MachineBasicBlock*, unsigned > > IncomingPredInfo; + void *IPI; + + /// VR - Current virtual register whose uses are being updated. + unsigned VR; + + /// VRC - Register class of the current virtual register. + const TargetRegisterClass *VRC; + + /// InsertedPHIs - If this is non-null, the MachineSSAUpdater adds all PHI + /// nodes that it creates to the vector. + SmallVectorImpl<MachineInstr*> *InsertedPHIs; + + const TargetInstrInfo *TII; + MachineRegisterInfo *MRI; +public: + /// MachineSSAUpdater constructor. If InsertedPHIs is specified, it will be + /// filled in with all PHI Nodes created by rewriting. + explicit MachineSSAUpdater(MachineFunction &MF, + SmallVectorImpl<MachineInstr*> *InsertedPHIs = 0); + ~MachineSSAUpdater(); + + /// Initialize - Reset this object to get ready for a new set of SSA + /// updates. + void Initialize(unsigned V); + + /// AddAvailableValue - Indicate that a rewritten value is available at the + /// end of the specified block with the specified value. + void AddAvailableValue(MachineBasicBlock *BB, unsigned V); + + /// HasValueForBlock - Return true if the MachineSSAUpdater already has a + /// value for the specified block. + bool HasValueForBlock(MachineBasicBlock *BB) const; + + /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is + /// live at the end of the specified block. + unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB); + + /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that + /// is live in the middle of the specified block. + /// + /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one + /// important case: if there is a definition of the rewritten value after the + /// 'use' in BB. Consider code like this: + /// + /// X1 = ... + /// SomeBB: + /// use(X) + /// X2 = ... + /// br Cond, SomeBB, OutBB + /// + /// In this case, there are two values (X1 and X2) added to the AvailableVals + /// set by the client of the rewriter, and those values are both live out of + /// their respective blocks. However, the use of X happens in the *middle* of + /// a block. Because of this, we need to insert a new PHI node in SomeBB to + /// merge the appropriate values, and this value isn't live out of the block. + /// + unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB); + + /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes, + /// which use their value in the corresponding predecessor. Note that this + /// will not work if the use is supposed to be rewritten to a value defined in + /// the same block as the use, but above it. Any 'AddAvailableValue's added + /// for the use's block will be considered to be below it. + void RewriteUse(MachineOperand &U); + +private: + void ReplaceRegWith(unsigned OldReg, unsigned NewReg); + unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB); + void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT + MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 8e89702..99f8c34 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -131,7 +131,7 @@ namespace llvm { /// TailDuplicate Pass - Duplicate blocks with unconditional branches /// into tails of their predecessors. - FunctionPass *createTailDuplicatePass(); + FunctionPass *createTailDuplicatePass(bool PreRegAlloc = false); /// IfConverter Pass - This pass performs machine code if conversion. FunctionPass *createIfConverterPass(); @@ -191,6 +191,10 @@ namespace llvm { /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. FunctionPass *createSjLjEHPass(const TargetLowering *tli); + /// createMaxStackAlignmentCalculatorPass() - Determine the maximum required + /// alignment for a function. + FunctionPass* createMaxStackAlignmentCalculatorPass(); + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index e586807..c09c634 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -110,6 +110,46 @@ class SelectionDAG { /// SelectionDAG. BumpPtrAllocator Allocator; + /// NodeOrdering - Assigns a "line number" value to each SDNode that + /// corresponds to the "line number" of the original LLVM instruction. This + /// used for turning off scheduling, because we'll forgo the normal scheduling + /// algorithm and output the instructions according to this ordering. + class NodeOrdering { + /// LineNo - The line of the instruction the node corresponds to. A value of + /// `0' means it's not assigned. + unsigned LineNo; + std::map<const SDNode*, unsigned> Order; + + void operator=(const NodeOrdering&); // Do not implement. + NodeOrdering(const NodeOrdering&); // Do not implement. + public: + NodeOrdering() : LineNo(0) {} + + void add(const SDNode *Node) { + assert(LineNo && "Invalid line number!"); + Order[Node] = LineNo; + } + void remove(const SDNode *Node) { + std::map<const SDNode*, unsigned>::iterator Itr = Order.find(Node); + if (Itr != Order.end()) + Order.erase(Itr); + } + void clear() { + Order.clear(); + LineNo = 1; + } + unsigned getLineNo(const SDNode *Node) { + unsigned LN = Order[Node]; + assert(LN && "Node isn't in ordering map!"); + return LN; + } + void newInst() { + ++LineNo; + } + + void dump() const; + } *Ordering; + /// VerifyNode - Sanity check the given node. Aborts if it is invalid. void VerifyNode(SDNode *N); @@ -120,6 +160,9 @@ class SelectionDAG { DenseSet<SDNode *> &visited, int level, bool &printed); + void operator=(const SelectionDAG&); // Do not implement. + SelectionDAG(const SelectionDAG&); // Do not implement. + public: SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli); ~SelectionDAG(); @@ -199,6 +242,13 @@ public: return Root = N; } + /// NewInst - Tell the ordering object that we're processing a new + /// instruction. + void NewInst() { + if (Ordering) + Ordering->newInst(); + } + /// Combine - This iterates over the nodes in the SelectionDAG, folding /// certain types of nodes together, or eliminating superfluous nodes. The /// Level argument controls whether Combine is allowed to produce nodes and @@ -220,7 +270,7 @@ public: /// /// Note that this is an involved process that may invalidate pointers into /// the graph. - void Legalize(bool TypesNeedLegalizing, CodeGenOpt::Level OptLevel); + void Legalize(CodeGenOpt::Level OptLevel); /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG /// that only uses vector math operations supported by the target. This is @@ -890,6 +940,16 @@ public: /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); + /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a + /// location that is 'Dist' units away from the location that the 'Base' load + /// is loading from. + bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, + unsigned Bytes, int Dist) const; + + /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if + /// it cannot be inferred. + unsigned InferPtrAlignment(SDValue Ptr) const; + private: bool RemoveNodeFromCSEMaps(SDNode *N); void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener); diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 4130d2c..bfd3492 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -113,7 +113,6 @@ protected: // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDValue N); SDNode *Select_UNDEF(const SDValue &N); - SDNode *Select_DBG_LABEL(const SDValue &N); SDNode *Select_EH_LABEL(const SDValue &N); void CannotYetSelect(SDValue N); void CannotYetSelectIntrinsic(SDValue N); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 950fd32..571db47 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -891,8 +891,9 @@ template<> struct DenseMapInfo<SDValue> { static bool isEqual(const SDValue &LHS, const SDValue &RHS) { return LHS == RHS; } - static bool isPod() { return true; } }; +template <> struct isPodLike<SDValue> { static const bool value = true; }; + /// simplify_type specializations - Allow casting operators to work directly on /// SDValues as if they were SDNode*'s. @@ -1095,7 +1096,7 @@ public: /// hasOneUse - Return true if there is exactly one use of this node. /// bool hasOneUse() const { - return !use_empty() && next(use_begin()) == use_end(); + return !use_empty() && llvm::next(use_begin()) == use_end(); } /// use_size - Return the number of uses of this node. This method takes @@ -2397,6 +2398,11 @@ public: SDNodeIterator operator++(int) { // Postincrement SDNodeIterator tmp = *this; ++*this; return tmp; } + size_t operator-(SDNodeIterator Other) const { + assert(Node == Other.Node && + "Cannot compare iterators of two different nodes!"); + return Operand - Other.Operand; + } static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); } static SDNodeIterator end (SDNode *N) { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 65d85fc..9a85ee1 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -343,8 +343,10 @@ namespace llvm { static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) { return (LHS == RHS); } - static inline bool isPod() { return false; } }; + + template <> struct isPodLike<SlotIndex> { static const bool value = true; }; + inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) { li.print(os); diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 45ef9b9..06e07f3 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -47,35 +47,36 @@ namespace llvm { f80 = 9, // This is a 80 bit floating point value f128 = 10, // This is a 128 bit floating point value ppcf128 = 11, // This is a PPC 128-bit floating point value - Flag = 12, // This is a condition code or machine flag. - - isVoid = 13, // This has no value - - v2i8 = 14, // 2 x i8 - v4i8 = 15, // 4 x i8 - v8i8 = 16, // 8 x i8 - v16i8 = 17, // 16 x i8 - v32i8 = 18, // 32 x i8 - v2i16 = 19, // 2 x i16 - v4i16 = 20, // 4 x i16 - v8i16 = 21, // 8 x i16 - v16i16 = 22, // 16 x i16 - v2i32 = 23, // 2 x i32 - v4i32 = 24, // 4 x i32 - v8i32 = 25, // 8 x i32 - v1i64 = 26, // 1 x i64 - v2i64 = 27, // 2 x i64 - v4i64 = 28, // 4 x i64 - - v2f32 = 29, // 2 x f32 - v4f32 = 30, // 4 x f32 - v8f32 = 31, // 8 x f32 - v2f64 = 32, // 2 x f64 - v4f64 = 33, // 4 x f64 + + v2i8 = 12, // 2 x i8 + v4i8 = 13, // 4 x i8 + v8i8 = 14, // 8 x i8 + v16i8 = 15, // 16 x i8 + v32i8 = 16, // 32 x i8 + v2i16 = 17, // 2 x i16 + v4i16 = 18, // 4 x i16 + v8i16 = 19, // 8 x i16 + v16i16 = 20, // 16 x i16 + v2i32 = 21, // 2 x i32 + v4i32 = 22, // 4 x i32 + v8i32 = 23, // 8 x i32 + v1i64 = 24, // 1 x i64 + v2i64 = 25, // 2 x i64 + v4i64 = 26, // 4 x i64 + + v2f32 = 27, // 2 x f32 + v4f32 = 28, // 4 x f32 + v8f32 = 29, // 8 x f32 + v2f64 = 30, // 2 x f64 + v4f64 = 31, // 4 x f64 FIRST_VECTOR_VALUETYPE = v2i8, LAST_VECTOR_VALUETYPE = v4f64, + Flag = 32, // This glues nodes together during pre-RA sched + + isVoid = 33, // This has no value + LAST_VALUETYPE = 34, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. @@ -166,6 +167,12 @@ namespace llvm { return *this; } } + + /// getScalarType - If this is a vector type, return the element type, + /// otherwise return this. + MVT getScalarType() const { + return isVector() ? getVectorElementType() : *this; + } MVT getVectorElementType() const { switch (SimpleTy) { @@ -524,6 +531,12 @@ namespace llvm { return V; } + /// getScalarType - If this is a vector type, return the element type, + /// otherwise return this. + EVT getScalarType() const { + return isVector() ? getVectorElementType() : *this; + } + /// getVectorElementType - Given a vector type, return the type of /// each element. EVT getVectorElementType() const { diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index 986555b..c8bb789 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -31,30 +31,31 @@ def f64 : ValueType<64 , 8>; // 64-bit floating point value def f80 : ValueType<80 , 9>; // 80-bit floating point value def f128 : ValueType<128, 10>; // 128-bit floating point value def ppcf128: ValueType<128, 11>; // PPC 128-bit floating point value -def FlagVT : ValueType<0 , 12>; // Condition code or machine flag -def isVoid : ValueType<0 , 13>; // Produces no value -def v2i8 : ValueType<16 , 14>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 15>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 16>; // 8 x i8 vector value -def v16i8 : ValueType<128, 17>; // 16 x i8 vector value -def v32i8 : ValueType<256, 18>; // 32 x i8 vector value -def v2i16 : ValueType<32 , 19>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 20>; // 4 x i16 vector value -def v8i16 : ValueType<128, 21>; // 8 x i16 vector value -def v16i16 : ValueType<256, 22>; // 16 x i16 vector value -def v2i32 : ValueType<64 , 23>; // 2 x i32 vector value -def v4i32 : ValueType<128, 24>; // 4 x i32 vector value -def v8i32 : ValueType<256, 25>; // 8 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 f64 vector value +def v2i8 : ValueType<16 , 12>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 13>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value +def v16i8 : ValueType<128, 15>; // 16 x i8 vector value +def v32i8 : ValueType<256, 16>; // 32 x i8 vector value +def v2i16 : ValueType<32 , 17>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 18>; // 4 x i16 vector value +def v8i16 : ValueType<128, 19>; // 8 x i16 vector value +def v16i16 : ValueType<256, 20>; // 16 x i16 vector value +def v2i32 : ValueType<64 , 21>; // 2 x i32 vector value +def v4i32 : ValueType<128, 22>; // 4 x i32 vector value +def v8i32 : ValueType<256, 23>; // 8 x i32 vector value +def v1i64 : ValueType<64 , 24>; // 1 x i64 vector value +def v2i64 : ValueType<128, 25>; // 2 x i64 vector value +def v4i64 : ValueType<256, 26>; // 4 x f64 vector value -def v2f32 : ValueType<64, 29>; // 2 x f32 vector value -def v4f32 : ValueType<128, 30>; // 4 x f32 vector value -def v8f32 : ValueType<256, 31>; // 8 x f32 vector value -def v2f64 : ValueType<128, 32>; // 2 x f64 vector value -def v4f64 : ValueType<256, 33>; // 4 x f64 vector value +def v2f32 : ValueType<64, 27>; // 2 x f32 vector value +def v4f32 : ValueType<128, 28>; // 4 x f32 vector value +def v8f32 : ValueType<256, 29>; // 8 x f32 vector value +def v2f64 : ValueType<128, 30>; // 2 x f64 vector value +def v4f64 : ValueType<256, 31>; // 4 x f64 vector value + +def FlagVT : ValueType<0 , 32>; // Pre-RA sched glue +def isVoid : ValueType<0 , 33>; // Produces no value def MetadataVT: ValueType<0, 250>; // Metadata diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 79edb02..8d2f63b 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -42,9 +42,10 @@ def hidden; def init; def multi_val; def one_or_more; +def optional; def really_hidden; def required; -def zero_or_one; +def comma_separated; // The 'case' construct. def case; @@ -77,6 +78,8 @@ def any_empty; def append_cmd; def forward; def forward_as; +def forward_value; +def forward_transformed_value; def stop_compilation; def unpack_values; def warning; diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 1e1dca2..a516409 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -70,6 +70,7 @@ namespace llvm { case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: case Intrinsic::dbg_declare: + case Intrinsic::dbg_value: return true; default: return false; } @@ -171,6 +172,25 @@ namespace llvm { } }; + /// DbgValueInst - This represents the llvm.dbg.value instruction. + /// + struct DbgValueInst : public DbgInfoIntrinsic { + Value *getValue() const { + return cast<MDNode>(getOperand(1))->getElement(0); + } + Value *getOffset() const { return getOperand(2); } + MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); } + + // 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; + } + static inline bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + }; + /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. /// struct MemIntrinsic : public IntrinsicInst { diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index b3b0678..6ff87ba 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -290,6 +290,9 @@ let Properties = [IntrNoMem] in { def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; def int_dbg_declare : Intrinsic<[llvm_void_ty], [llvm_descriptor_ty, llvm_metadata_ty]>; + def int_dbg_value : Intrinsic<[llvm_void_ty], + [llvm_metadata_ty, llvm_i64_ty, + llvm_metadata_ty]>; } //===------------------ Exception Handling Intrinsics----------------------===// diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h index 0ee18d5..2145bf8 100644 --- a/include/llvm/LinkAllVMCore.h +++ b/include/llvm/LinkAllVMCore.h @@ -35,6 +35,7 @@ #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SlowOperationInformer.h" +#include <cstdlib> namespace { struct ForceVMCoreLinking { diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 909ccde..f3e4dfd 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -111,12 +111,10 @@ public: virtual void assignPassManager(PMStack &, PassManagerType = PMT_Unknown) {} /// Check if available pass managers are suitable for this pass or not. - virtual void preparePassManager(PMStack &) {} + virtual void preparePassManager(PMStack &); /// Return what kind of Pass Manager can manage this pass. - virtual PassManagerType getPotentialPassManagerType() const { - return PMT_Unknown; - } + virtual PassManagerType getPotentialPassManagerType() const; // Access AnalysisResolver inline void setResolver(AnalysisResolver *AR) { @@ -132,9 +130,7 @@ public: /// particular analysis result to this function, it can then use the /// getAnalysis<AnalysisType>() function, below. /// - virtual void getAnalysisUsage(AnalysisUsage &) const { - // By default, no analysis results are used, all are invalidated. - } + virtual void getAnalysisUsage(AnalysisUsage &) const; /// releaseMemory() - This member can be implemented by a pass if it wants to /// be able to release its memory when it is no longer needed. The default @@ -147,11 +143,11 @@ public: /// Optionally implement this function to release pass memory when it is no /// longer used. /// - virtual void releaseMemory() {} + virtual void releaseMemory(); /// verifyAnalysis() - This member can be implemented by a analysis pass to /// check state of analysis information. - virtual void verifyAnalysis() const {} + virtual void verifyAnalysis() const; // dumpPassStructure - Implement the -debug-passes=PassStructure option virtual void dumpPassStructure(unsigned Offset = 0); @@ -221,9 +217,7 @@ public: PassManagerType T = PMT_ModulePassManager); /// Return what kind of Pass Manager can manage this pass. - virtual PassManagerType getPotentialPassManagerType() const { - return PMT_ModulePassManager; - } + virtual PassManagerType getPotentialPassManagerType() const; explicit ModulePass(intptr_t pid) : Pass(pid) {} explicit ModulePass(const void *pid) : Pass(pid) {} @@ -245,7 +239,7 @@ public: /// and if it does, the overloaded version of initializePass may get access to /// these passes with getAnalysis<>. /// - virtual void initializePass() {} + virtual void initializePass(); /// ImmutablePasses are never run. /// @@ -276,7 +270,7 @@ public: /// doInitialization - Virtual method overridden by subclasses to do /// any necessary per-module initialization. /// - virtual bool doInitialization(Module &) { return false; } + virtual bool doInitialization(Module &); /// runOnFunction - Virtual method overriden by subclasses to do the /// per-function processing of the pass. @@ -286,7 +280,7 @@ public: /// doFinalization - Virtual method overriden by subclasses to do any post /// processing needed after all passes have run. /// - virtual bool doFinalization(Module &) { return false; } + virtual bool doFinalization(Module &); /// runOnModule - On a module, we run this pass by initializing, /// ronOnFunction'ing once for every function in the module, then by @@ -303,9 +297,7 @@ public: PassManagerType T = PMT_FunctionPassManager); /// Return what kind of Pass Manager can manage this pass. - virtual PassManagerType getPotentialPassManagerType() const { - return PMT_FunctionPassManager; - } + virtual PassManagerType getPotentialPassManagerType() const; }; @@ -328,12 +320,12 @@ public: /// doInitialization - Virtual method overridden by subclasses to do /// any necessary per-module initialization. /// - virtual bool doInitialization(Module &) { return false; } + virtual bool doInitialization(Module &); /// doInitialization - Virtual method overridden by BasicBlockPass subclasses /// to do any necessary per-function initialization. /// - virtual bool doInitialization(Function &) { return false; } + virtual bool doInitialization(Function &); /// runOnBasicBlock - Virtual method overriden by subclasses to do the /// per-basicblock processing of the pass. @@ -343,12 +335,12 @@ public: /// doFinalization - Virtual method overriden by BasicBlockPass subclasses to /// do any post processing needed after all passes have run. /// - virtual bool doFinalization(Function &) { return false; } + virtual bool doFinalization(Function &); /// doFinalization - Virtual method overriden by subclasses to do any post /// processing needed after all passes have run. /// - virtual bool doFinalization(Module &) { return false; } + virtual bool doFinalization(Module &); // To run this pass on a function, we simply call runOnBasicBlock once for @@ -360,9 +352,7 @@ public: PassManagerType T = PMT_BasicBlockPassManager); /// Return what kind of Pass Manager can manage this pass. - virtual PassManagerType getPotentialPassManagerType() const { - return PMT_BasicBlockPassManager; - } + virtual PassManagerType getPotentialPassManagerType() const; }; /// If the user specifies the -time-passes argument on an LLVM tool command line diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 2e65fdd..7f8b10c 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -986,7 +986,7 @@ template<class DataType> class list_storage<DataType, bool> : public std::vector<DataType> { public: template<class T> - void addValue(const T &V) { push_back(V); } + void addValue(const T &V) { std::vector<DataType>::push_back(V); } }; @@ -1011,7 +1011,7 @@ class list : public Option, public list_storage<DataType, Storage> { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - addValue(Val); + list_storage<DataType, Storage>::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index da31f98..8861a20 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -70,6 +70,16 @@ #define DISABLE_INLINE #endif +// ALWAYS_INLINE - On compilers where we have a directive to do so, mark a +// method "always inline" because it is performance sensitive. +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +#define ALWAYS_INLINE __attribute__((always_inline)) +#else +// TODO: No idea how to do this with MSVC. +#define ALWAYS_INLINE +#endif + + #ifdef __GNUC__ #define NORETURN __attribute__((noreturn)) #elif defined(_MSC_VER) diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index afa828c..e8bc0ce 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -63,7 +63,8 @@ void SetCurrentDebugType(const char *Type); /// This will emit the debug information if -debug is present, and -debug-only /// is not specified, or is specified as "bitset". #define DEBUG_WITH_TYPE(TYPE, X) \ - do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0) + do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \ + } while (0) #else #define isCurrentDebugType(X) (false) diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index 362390f..6814f63 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -66,7 +66,7 @@ namespace llvm { }; // Specialize DenseMapInfo for DebugLocTuple. - template<> struct DenseMapInfo<DebugLocTuple> { + template<> struct DenseMapInfo<DebugLocTuple> { static inline DebugLocTuple getEmptyKey() { return DebugLocTuple(0, 0, ~0U, ~0U); } @@ -85,9 +85,9 @@ namespace llvm { LHS.Line == RHS.Line && LHS.Col == RHS.Col; } - - static bool isPod() { return true; } }; + template <> struct isPodLike<DebugLocTuple> {static const bool value = true;}; + /// DebugLocTracker - This class tracks debug location information. /// diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h index 6067795..4d24ada 100644 --- a/include/llvm/Support/ErrorHandling.h +++ b/include/llvm/Support/ErrorHandling.h @@ -79,9 +79,10 @@ namespace llvm { /// Use this instead of assert(0), so that the compiler knows this path /// is not reachable even for NDEBUG builds. #ifndef NDEBUG -#define llvm_unreachable(msg) llvm_unreachable_internal(msg, __FILE__, __LINE__) +#define llvm_unreachable(msg) \ + ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) #else -#define llvm_unreachable(msg) llvm_unreachable_internal() +#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() #endif #endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h index f5915c9..e5e7fc7 100644 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/include/llvm/Support/GetElementPtrTypeIterator.h @@ -84,7 +84,7 @@ namespace llvm { inline gep_type_iterator gep_type_begin(const User *GEP) { return gep_type_iterator::begin(GEP->getOperand(0)->getType(), - GEP->op_begin()+1); + GEP->op_begin()+1); } inline gep_type_iterator gep_type_end(const User *GEP) { return gep_type_iterator::end(GEP->op_end()); diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 2db2477..1310d70 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -269,6 +269,27 @@ public: return Insert(IndirectBrInst::Create(Addr, NumDests)); } + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, const Twine &Name = "") { + Value *Args[] = { 0 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args), Name); + } + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, Value *Arg1, + const Twine &Name = "") { + Value *Args[] = { Arg1 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args+1), Name); + } + InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, Value *Arg1, + Value *Arg2, Value *Arg3, + const Twine &Name = "") { + Value *Args[] = { Arg1, Arg2, Arg3 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args+3), Name); + } /// CreateInvoke - Create an invoke instruction. template<typename InputIterator> InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, @@ -386,18 +407,39 @@ public: return Folder.CreateShl(LC, RC); return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); } + Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateShl(LC, RHSC); + return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name); + } + Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateLShr(LC, RC); return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); } + Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateLShr(LC, RHSC); + return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name); + } + Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateAShr(LC, RC); return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } + Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateSShr(LC, RHSC); + return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name); + } + Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *RC = dyn_cast<Constant>(RHS)) { if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue()) diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index a9872a7..82c3cae 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -254,15 +254,18 @@ struct DenseMapInfo<AssertingVH<T> > { static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { return LHS == RHS; } - static bool isPod() { +}; + +template <typename T> +struct isPodLike<AssertingVH<T> > { #ifdef NDEBUG - return true; + static const bool value = true; #else - return false; + static const bool value = false; #endif - } }; + /// TrackingVH - This is a value handle that tracks a Value (or Value subclass), /// even across RAUW operations. /// diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index a78e81f..2b3341d 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -186,14 +186,12 @@ public: // Inline fast path, particulary for constant strings where a sufficiently // smart compiler will simplify strlen. - this->operator<<(StringRef(Str)); - return *this; + return this->operator<<(StringRef(Str)); } raw_ostream &operator<<(const std::string &Str) { // Avoid the fast path, it would only increase code size for a marginal win. - write(Str.data(), Str.length()); - return *this; + return write(Str.data(), Str.length()); } raw_ostream &operator<<(unsigned long N); @@ -202,13 +200,11 @@ public: raw_ostream &operator<<(long long N); raw_ostream &operator<<(const void *P); raw_ostream &operator<<(unsigned int N) { - this->operator<<(static_cast<unsigned long>(N)); - return *this; + return this->operator<<(static_cast<unsigned long>(N)); } raw_ostream &operator<<(int N) { - this->operator<<(static_cast<long>(N)); - return *this; + return this->operator<<(static_cast<long>(N)); } raw_ostream &operator<<(double N); diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index ce916b5..515295b 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -17,13 +17,15 @@ #ifndef LLVM_SUPPORT_TYPE_TRAITS_H #define LLVM_SUPPORT_TYPE_TRAITS_H +#include <utility> + // This is actually the conforming implementation which works with abstract // classes. However, enough compilers have trouble with it that most will use // the one in boost/type_traits/object_traits.hpp. This implementation actually // works with VC7.0, but other interactions seem to fail when we use it. namespace llvm { - + namespace dont_use { // These two functions should never be used. They are helpers to @@ -48,6 +50,23 @@ struct is_class public: enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) }; }; + + +/// isPodLike - This is a type trait that is used to determine whether a given +/// type can be copied around with memcpy instead of running ctors etc. +template <typename T> +struct isPodLike { + // If we don't know anything else, we can (at least) assume that all non-class + // types are PODs. + static const bool value = !is_class<T>::value; +}; + +// std::pair's are pod-like if their elements are. +template<typename T, typename U> +struct isPodLike<std::pair<T, U> > { + static const bool value = isPodLike<T>::value & isPodLike<U>::value; +}; + /// \brief Metafunction that determines whether the two given types are /// equivalent. diff --git a/include/llvm/System/Atomic.h b/include/llvm/System/Atomic.h index 0c05d69..fc19369 100644 --- a/include/llvm/System/Atomic.h +++ b/include/llvm/System/Atomic.h @@ -20,7 +20,11 @@ namespace llvm { namespace sys { void MemoryFence(); +#ifdef _MSC_VER + typedef long cas_flag; +#else typedef uint32_t cas_flag; +#endif cas_flag CompareAndSwap(volatile cas_flag* ptr, cas_flag new_value, cas_flag old_value); diff --git a/include/llvm/System/DataTypes.h.cmake b/include/llvm/System/DataTypes.h.cmake index 180c86c..d9ca273 100644 --- a/include/llvm/System/DataTypes.h.cmake +++ b/include/llvm/System/DataTypes.h.cmake @@ -118,14 +118,33 @@ typedef signed int ssize_t; #define INT32_MAX 2147483647 #define INT32_MIN -2147483648 #define UINT32_MAX 4294967295U -#define INT8_C(C) C -#define UINT8_C(C) C -#define INT16_C(C) C -#define UINT16_C(C) C -#define INT32_C(C) C -#define UINT32_C(C) C ## U -#define INT64_C(C) ((int64_t) C ## LL) -#define UINT64_C(C) ((uint64_t) C ## ULL) +/* Certain compatibility updates to VC++ introduce the `cstdint' + * header, which defines the INT*_C macros. On default installs they + * are absent. */ +#ifndef INT8_C +# define INT8_C(C) C +#endif +#ifndef UINT8_C +# define UINT8_C(C) C +#endif +#ifndef INT16_C +# define INT16_C(C) C +#endif +#ifndef UINT16_C +# define UINT16_C(C) C +#endif +#ifndef INT32_C +# define INT32_C(C) C +#endif +#ifndef UINT32_C +# define UINT32_C(C) C ## U +#endif +#ifndef INT64_C +# define INT64_C(C) ((int64_t) C ## LL) +#endif +#ifndef UINT64_C +# define UINT64_C(C) ((uint64_t) C ## ULL) +#endif #endif /* _MSC_VER */ /* Set defaults for constants which we cannot find. */ diff --git a/include/llvm/System/DataTypes.h.in b/include/llvm/System/DataTypes.h.in index d574910..1f8ce79 100644 --- a/include/llvm/System/DataTypes.h.in +++ b/include/llvm/System/DataTypes.h.in @@ -36,8 +36,6 @@ #include <math.h> #endif -#ifndef _MSC_VER - /* Note that this header's correct operation depends on __STDC_LIMIT_MACROS being defined. We would define it here, but in order to prevent Bad Things happening when system headers or C++ STL headers include stdint.h before we @@ -89,40 +87,6 @@ typedef u_int64_t uint64_t; #define UINT32_MAX 4294967295U #endif -#else /* _MSC_VER */ -/* Visual C++ doesn't provide standard integer headers, but it does provide - built-in data types. */ -#include <stdlib.h> -#include <stddef.h> -#include <sys/types.h> -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed int ssize_t; -#define INT8_MAX 127 -#define INT8_MIN -128 -#define UINT8_MAX 255 -#define INT16_MAX 32767 -#define INT16_MIN -32768 -#define UINT16_MAX 65535 -#define INT32_MAX 2147483647 -#define INT32_MIN -2147483648 -#define UINT32_MAX 4294967295U -#define INT8_C(C) C -#define UINT8_C(C) C -#define INT16_C(C) C -#define UINT16_C(C) C -#define INT32_C(C) C -#define UINT32_C(C) C ## U -#define INT64_C(C) ((int64_t) C ## LL) -#define UINT64_C(C) ((uint64_t) C ## ULL) -#endif /* _MSC_VER */ - /* Set defaults for constants which we cannot find. */ #if !defined(INT64_MAX) # define INT64_MAX 9223372036854775807LL diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index e1d052e..2e63188 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -30,7 +30,6 @@ class Type; class IntegerType; class StructType; class StructLayout; -class StructLayoutMap; class GlobalVariable; class LLVMContext; @@ -60,8 +59,6 @@ struct TargetAlignElem { unsigned char pref_align, uint32_t bit_width); /// Equality predicate bool operator==(const TargetAlignElem &rhs) const; - /// output stream operator - std::ostream &dump(std::ostream &os) const; }; class TargetData : public ImmutablePass { @@ -86,7 +83,7 @@ private: static const TargetAlignElem InvalidAlignmentElem; // The StructType -> StructLayout map. - mutable StructLayoutMap *LayoutMap; + mutable void *LayoutMap; //! Set/initialize target alignments void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, @@ -153,7 +150,7 @@ public: /// The width is specified in bits. /// bool isLegalInteger(unsigned Width) const { - for (unsigned i = 0, e = LegalIntWidths.size(); i != e; ++i) + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) if (LegalIntWidths[i] == Width) return true; return false; diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 1ba6b2f..1bcd6fd 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -26,6 +26,7 @@ class LiveVariables; class CalleeSavedInfo; class SDNode; class SelectionDAG; +class MachineMemOperand; template<class T> class SmallVectorImpl; @@ -182,11 +183,13 @@ public: /// hasLoadFromStackSlot - If the specified machine instruction has /// a load from a stack slot, return true along with the FrameIndex - /// of the loaded stack slot. If not, return false. Unlike + /// of the loaded stack slot and the machine mem operand containing + /// the reference. If not, return false. Unlike /// isLoadFromStackSlot, this returns true for any instructions that /// loads from the stack. This is just a hint, as some cases may be /// missed. virtual bool hasLoadFromStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, int &FrameIndex) const { return 0; } @@ -205,17 +208,18 @@ public: /// stack locations as well. This uses a heuristic so it isn't /// reliable for correctness. virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, - int &FrameIndex) const { + int &FrameIndex) const { return 0; } /// hasStoreToStackSlot - If the specified machine instruction has a /// store to a stack slot, return true along with the FrameIndex of - /// the loaded stack slot. If not, return false. Unlike - /// isStoreToStackSlot, this returns true for any instructions that - /// loads from the stack. This is just a hint, as some cases may be - /// missed. + /// the loaded stack slot and the machine mem operand containing the + /// reference. If not, return false. Unlike isStoreToStackSlot, + /// this returns true for any instructions that loads from the + /// stack. This is just a hint, as some cases may be missed. virtual bool hasStoreToStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, int &FrameIndex) const { return 0; } @@ -282,11 +286,10 @@ public: /// just return false, leaving TBB/FBB null. /// 2. If this block ends with only an unconditional branch, it sets TBB to be /// the destination block. - /// 3. If this block ends with an conditional branch and it falls through to - /// a successor block, it sets TBB to be the branch destination block and - /// a list of operands that evaluate the condition. These - /// operands can be passed to other TargetInstrInfo methods to create new - /// branches. + /// 3. If this block ends with a conditional branch and it falls through to a + /// successor block, it sets TBB to be the branch destination block and a + /// list of operands that evaluate the condition. These operands can be + /// passed to other TargetInstrInfo methods to create new branches. /// 4. If this block ends with a conditional branch followed by an /// unconditional branch, it returns the 'true' destination in TBB, the /// 'false' destination in FBB, and a list of operands that evaluate the @@ -461,14 +464,6 @@ public: return 0; } - /// BlockHasNoFallThrough - Return true if the specified block does not - /// fall-through into its successor block. This is primarily used when a - /// branch is unanalyzable. It is useful for things like unconditional - /// indirect branches (jump tables). - virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { - return false; - } - /// ReverseBranchCondition - Reverses the branch condition of the specified /// condition list, returning false on success and true if it cannot be /// reversed. diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ca51102..9536e04 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -857,12 +857,6 @@ public: virtual bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const; - /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a - /// location that is 'Dist' units away from the location that the 'Base' load - /// is loading from. - bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, - int Dist, const MachineFrameInfo *MFI) const; - /// PerformDAGCombine - This method will be invoked for all target nodes and /// for any target-independent nodes that the target has registered with /// invoke it for. @@ -978,7 +972,7 @@ protected: /// not work with the with specified type and indicate what to do about it. void setLoadExtAction(unsigned ExtType, MVT VT, LegalizeAction Action) { - assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE && + assert((unsigned)VT.SimpleTy*2 < 63 && ExtType < array_lengthof(LoadExtActions) && "Table isn't big enough!"); LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.SimpleTy*2); @@ -990,7 +984,7 @@ protected: void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action) { assert((unsigned)ValVT.SimpleTy < array_lengthof(TruncStoreActions) && - (unsigned)MemVT.SimpleTy < MVT::LAST_VALUETYPE && + (unsigned)MemVT.SimpleTy*2 < 63 && "Table isn't big enough!"); TruncStoreActions[ValVT.SimpleTy] &= ~(uint64_t(3UL) << MemVT.SimpleTy*2); TruncStoreActions[ValVT.SimpleTy] |= (uint64_t)Action << MemVT.SimpleTy*2; diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index cb29c73..dec0b1d 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -299,7 +299,7 @@ public: /// FirstVirtualRegister - This is the first register number that is /// considered to be a 'virtual' register, which is part of the SSA /// namespace. This must be the same for all targets, which means that each - /// target is limited to 1024 registers. + /// target is limited to this fixed number of registers. FirstVirtualRegister = 1024 }; |