diff options
Diffstat (limited to 'include/llvm')
65 files changed, 1372 insertions, 1746 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 30d998f..f81109a 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -191,6 +191,7 @@ namespace llvm { static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { return APFloat(Sem, fcInfinity, Negative); } + /// getNaN - Factory for QNaN values. /// /// \param Negative - True iff the NaN generated should be negative. @@ -201,6 +202,26 @@ namespace llvm { return APFloat(Sem, fcNaN, Negative, type); } + /// getLargest - Returns the largest finite number in the given + /// semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getLargest(const fltSemantics &Sem, bool Negative = false); + + /// getSmallest - Returns the smallest (by magnitude) finite number + /// in the given semantics. Might be denormalized, which implies a + /// relative loss of precision. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false); + + /// getSmallestNormalized - Returns the smallest (by magnitude) + /// normalized finite number in the given semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallestNormalized(const fltSemantics &Sem, + bool Negative = false); + /// Profile - Used to insert APFloat objects, or objects that contain /// APFloat objects, into FoldingSets. void Profile(FoldingSetNodeID& NID) const; @@ -277,6 +298,30 @@ namespace llvm { /* Return an arbitrary integer value usable for hashing. */ uint32_t getHashValue() const; + /// Converts this value into a decimal string. + /// + /// \param FormatPrecision The maximum number of digits of + /// precision to output. If there are fewer digits available, + /// zero padding will not be used unless the value is + /// integral and small enough to be expressed in + /// FormatPrecision digits. 0 means to use the natural + /// precision of the number. + /// \param FormatMaxPadding The maximum number of zeros to + /// consider inserting before falling back to scientific + /// notation. 0 means to always use scientific notation. + /// + /// Number Precision MaxPadding Result + /// ------ --------- ---------- ------ + /// 1.01E+4 5 2 10100 + /// 1.01E+4 4 2 1.01E+4 + /// 1.01E+4 5 1 1.01E+4 + /// 1.01E-2 5 2 0.0101 + /// 1.01E-2 4 2 0.0101 + /// 1.01E-2 4 1 1.01E-2 + void toString(SmallVectorImpl<char> &Str, + unsigned FormatPrecision = 0, + unsigned FormatMaxPadding = 3); + private: /* Trivial queries. */ diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 8b62f2d..8b161ea 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -46,7 +46,7 @@ public: typedef ValueT mapped_type; typedef BucketT value_type; - DenseMap(const DenseMap& other) { + DenseMap(const DenseMap &other) { NumBuckets = 0; CopyFrom(other); } @@ -55,6 +55,12 @@ public: init(NumInitBuckets); } + template<typename InputIt> + DenseMap(const InputIt &I, const InputIt &E) { + init(64); + insert(I, E); + } + ~DenseMap() { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index 3afcabd..d38ce4c 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -72,7 +72,7 @@ class scc_iterator SCCNodeStack.push_back(N); MinVisitNumStack.push_back(visitNum); VisitStack.push_back(std::make_pair(N, GT::child_begin(N))); - //errs() << "TarjanSCC: Node " << N << + //dbgs() << "TarjanSCC: Node " << N << // " : visitNum = " << visitNum << "\n"; } @@ -107,7 +107,7 @@ class scc_iterator if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum) MinVisitNumStack.back() = minVisitNum; - //errs() << "TarjanSCC: Popped node " << visitingN << + //dbgs() << "TarjanSCC: Popped node " << visitingN << // " : minVisitNum = " << minVisitNum << "; Node visit num = " << // nodeVisitNumbers[visitingN] << "\n"; diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index b16649e..89acefd 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -80,55 +80,56 @@ protected: return BeginX == static_cast<const void*>(&FirstEl); } + /// size_in_bytes - This returns size()*sizeof(T). + size_t size_in_bytes() const { + return size_t((char*)EndX - (char*)BeginX); + } + + /// capacity_in_bytes - This returns capacity()*sizeof(T). + size_t capacity_in_bytes() const { + return size_t((char*)CapacityX - (char*)BeginX); + } + + /// grow_pod - This is an implementation of the grow() method which only works + /// on POD-like datatypes and is out of line to reduce code duplication. + void grow_pod(size_t MinSizeInBytes, size_t TSize); 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; } +class SmallVectorTemplateCommon : public SmallVectorBase { +protected: + void setEnd(T *P) { this->EndX = P; } public: - // Default ctor - Initialize to empty. - explicit SmallVectorImpl(unsigned N) : SmallVectorBase(N*sizeof(T)) { - } - - ~SmallVectorImpl() { - // Destroy the constructed elements in the vector. - destroy_range(begin(), end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!isSmall()) - operator delete(begin()); - } - + SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {} + typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T value_type; 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 T &reference; typedef const T &const_reference; typedef T *pointer; typedef const T *const_pointer; - + // forward iterator creation methods. - 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; } + iterator begin() { return (iterator)this->BeginX; } + const_iterator begin() const { return (const_iterator)this->BeginX; } + iterator end() { return (iterator)this->EndX; } + const_iterator end() const { return (const_iterator)this->EndX; } +protected: + iterator capacity_ptr() { return (iterator)this->CapacityX; } + const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;} public: - + // reverse iterator creation methods. reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } @@ -169,248 +170,359 @@ public: const_reference back() const { return end()[-1]; } +}; + +/// SmallVectorTemplateBase<isPodLike = false> - This is where we put method +/// implementations that are designed to work with non-POD-like T's. +template <typename T, bool isPodLike> +class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { +public: + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} - void push_back(const_reference Elt) { - if (EndX < CapacityX) { - Retry: - new (end()) T(Elt); - setEnd(end()+1); - return; + static void destroy_range(T *S, T *E) { + while (S != E) { + --E; + E->~T(); } - grow(); - goto Retry; } - - void pop_back() { - setEnd(end()-1); - end()->~T(); + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template<typename It1, typename It2> + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + std::uninitialized_copy(I, E, Dest); } + + /// grow - double the size of the allocated memory, guaranteeing space for at + /// least one more element or MinSize if specified. + void grow(size_t MinSize = 0); +}; - T pop_back_val() { - T Result = back(); - pop_back(); - return Result; +// Define this out-of-line to dissuade the C++ compiler from inlining it. +template <typename T, bool isPodLike> +void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { + size_t CurCapacity = this->capacity(); + size_t CurSize = this->size(); + size_t NewCapacity = 2*CurCapacity; + if (NewCapacity < MinSize) + NewCapacity = MinSize; + T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T))); + + // Copy the elements over. + this->uninitialized_copy(this->begin(), this->end(), NewElts); + + // Destroy the original elements. + destroy_range(this->begin(), this->end()); + + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + operator delete(this->begin()); + + this->setEnd(NewElts+CurSize); + this->BeginX = NewElts; + this->CapacityX = this->begin()+NewCapacity; +} + + +/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method +/// implementations that are designed to work with POD-like T's. +template <typename T> +class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> { +public: + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} + + // No need to do a destroy loop for POD's. + static void destroy_range(T *, T *) {} + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template<typename It1, typename It2> + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + // Use memcpy for PODs: std::uninitialized_copy optimizes to memmove, memcpy + // is better. + memcpy(&*Dest, &*I, (E-I)*sizeof(T)); } - + + /// grow - double the size of the allocated memory, guaranteeing space for at + /// least one more element or MinSize if specified. + void grow(size_t MinSize = 0) { + this->grow_pod(MinSize*sizeof(T), sizeof(T)); + } +}; + + +/// 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 SmallVectorTemplateBase<T, isPodLike<T>::value> { + typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass; +public: + typedef typename SuperClass::iterator iterator; + typedef typename SuperClass::size_type size_type; + + // Default ctor - Initialize to empty. + explicit SmallVectorImpl(unsigned N) + : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) { + } + + ~SmallVectorImpl() { + // Destroy the constructed elements in the vector. + this->destroy_range(this->begin(), this->end()); + + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + operator delete(this->begin()); + } + + void clear() { - destroy_range(begin(), end()); - EndX = BeginX; + this->destroy_range(this->begin(), this->end()); + this->EndX = this->BeginX; } void resize(unsigned N) { - if (N < size()) { - destroy_range(begin()+N, end()); - setEnd(begin()+N); - } else if (N > size()) { - if (capacity() < N) - grow(N); - construct_range(end(), begin()+N, T()); - setEnd(begin()+N); + if (N < this->size()) { + this->destroy_range(this->begin()+N, this->end()); + this->setEnd(this->begin()+N); + } else if (N > this->size()) { + if (this->capacity() < N) + this->grow(N); + this->construct_range(this->end(), this->begin()+N, T()); + this->setEnd(this->begin()+N); } } void resize(unsigned N, const T &NV) { - if (N < size()) { - destroy_range(begin()+N, end()); - setEnd(begin()+N); - } else if (N > size()) { - if (capacity() < N) - grow(N); - construct_range(end(), begin()+N, NV); - setEnd(begin()+N); + if (N < this->size()) { + this->destroy_range(this->begin()+N, this->end()); + this->setEnd(this->begin()+N); + } else if (N > this->size()) { + if (this->capacity() < N) + this->grow(N); + construct_range(this->end(), this->begin()+N, NV); + this->setEnd(this->begin()+N); } } void reserve(unsigned N) { - if (capacity() < N) - grow(N); + if (this->capacity() < N) + this->grow(N); } - + + void push_back(const T &Elt) { + if (this->EndX < this->CapacityX) { + Retry: + new (this->end()) T(Elt); + this->setEnd(this->end()+1); + return; + } + this->grow(); + goto Retry; + } + + void pop_back() { + this->setEnd(this->end()-1); + this->end()->~T(); + } + + T pop_back_val() { + T Result = this->back(); + pop_back(); + return Result; + } + + void swap(SmallVectorImpl &RHS); - + /// append - Add the specified range to the end of the SmallVector. /// template<typename in_iter> 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_ptr()-end())) - grow(size()+NumInputs); - + if (NumInputs > size_type(this->capacity_ptr()-this->end())) + this->grow(this->size()+NumInputs); + // Copy the new elements over. - std::uninitialized_copy(in_start, in_end, end()); - setEnd(end() + NumInputs); + // TODO: NEED To compile time dispatch on whether in_iter is a random access + // iterator to use the fast uninitialized_copy. + std::uninitialized_copy(in_start, in_end, this->end()); + this->setEnd(this->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_ptr()-end())) - grow(size()+NumInputs); - + if (NumInputs > size_type(this->capacity_ptr()-this->end())) + this->grow(this->size()+NumInputs); + // Copy the new elements over. - std::uninitialized_fill_n(end(), NumInputs, Elt); - setEnd(end() + NumInputs); + std::uninitialized_fill_n(this->end(), NumInputs, Elt); + this->setEnd(this->end() + NumInputs); } - + void assign(unsigned NumElts, const T &Elt) { clear(); - if (capacity() < NumElts) - grow(NumElts); - setEnd(begin()+NumElts); - construct_range(begin(), end(), Elt); + if (this->capacity() < NumElts) + this->grow(NumElts); + this->setEnd(this->begin()+NumElts); + construct_range(this->begin(), this->end(), Elt); } - + iterator erase(iterator I) { iterator N = I; // Shift all elts down one. - std::copy(I+1, end(), I); + std::copy(I+1, this->end(), I); // Drop the last elt. pop_back(); return(N); } - + 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, this->end(), S); // Drop the last elts. - destroy_range(I, end()); - setEnd(I); + this->destroy_range(I, this->end()); + this->setEnd(I); return(N); } - + iterator insert(iterator I, const T &Elt) { - if (I == end()) { // Important special case for empty vector. + if (I == this->end()) { // Important special case for empty vector. push_back(Elt); - return end()-1; + return this->end()-1; } - - if (EndX < CapacityX) { - Retry: - new (end()) T(back()); - setEnd(end()+1); + + if (this->EndX < this->CapacityX) { + Retry: + new (this->end()) T(this->back()); + this->setEnd(this->end()+1); // Push everything else over. - std::copy_backward(I, end()-1, end()); + std::copy_backward(I, this->end()-1, this->end()); *I = Elt; return I; } - size_t EltNo = I-begin(); - grow(); - I = begin()+EltNo; + size_t EltNo = I-this->begin(); + this->grow(); + I = this->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 == this->end()) { // Important special case for empty vector. append(NumToInsert, Elt); - return end()-1; + return this->end()-1; } - + // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I-begin(); - + size_t InsertElt = I - this->begin(); + // Ensure there is enough space. - reserve(static_cast<unsigned>(size() + NumToInsert)); - + reserve(static_cast<unsigned>(this->size() + NumToInsert)); + // Uninvalidate the iterator. - I = begin()+InsertElt; - + I = this->begin()+InsertElt; + // If there are more elements between the insertion point and the end of the // range than there are being inserted, we can use a simple approach to // 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()); - + if (size_t(this->end()-I) >= NumToInsert) { + T *OldEnd = this->end(); + append(this->end()-NumToInsert, this->end()); + // Copy the existing elements that get replaced. std::copy_backward(I, OldEnd-NumToInsert, OldEnd); - + std::fill_n(I, NumToInsert, Elt); return I; } - + // Otherwise, we're inserting more elements than exist already, and we're // not inserting at the end. - + // Copy over the elements that we're about to overwrite. - T *OldEnd = end(); - setEnd(end() + NumToInsert); + T *OldEnd = this->end(); + this->setEnd(this->end() + NumToInsert); size_t NumOverwritten = OldEnd-I; - std::uninitialized_copy(I, OldEnd, end()-NumOverwritten); - + this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); + // Replace the overwritten part. std::fill_n(I, NumOverwritten, Elt); - + // Insert the non-overwritten middle part. std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); return I; } - + template<typename ItTy> iterator insert(iterator I, ItTy From, ItTy To) { - if (I == end()) { // Important special case for empty vector. + if (I == this->end()) { // Important special case for empty vector. append(From, To); - return end()-1; + return this->end()-1; } - + size_t NumToInsert = std::distance(From, To); // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I-begin(); - + size_t InsertElt = I - this->begin(); + // Ensure there is enough space. - reserve(static_cast<unsigned>(size() + NumToInsert)); - + reserve(static_cast<unsigned>(this->size() + NumToInsert)); + // Uninvalidate the iterator. - I = begin()+InsertElt; - + I = this->begin()+InsertElt; + // If there are more elements between the insertion point and the end of the // range than there are being inserted, we can use a simple approach to // 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()); - + if (size_t(this->end()-I) >= NumToInsert) { + T *OldEnd = this->end(); + append(this->end()-NumToInsert, this->end()); + // Copy the existing elements that get replaced. std::copy_backward(I, OldEnd-NumToInsert, OldEnd); - + std::copy(From, To, I); return I; } - + // Otherwise, we're inserting more elements than exist already, and we're // not inserting at the end. - + // Copy over the elements that we're about to overwrite. - T *OldEnd = end(); - setEnd(end() + NumToInsert); + T *OldEnd = this->end(); + this->setEnd(this->end() + NumToInsert); size_t NumOverwritten = OldEnd-I; - std::uninitialized_copy(I, OldEnd, end()-NumOverwritten); - + this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); + // Replace the overwritten part. std::copy(From, From+NumOverwritten, I); - + // Insert the non-overwritten middle part. - std::uninitialized_copy(From+NumOverwritten, To, OldEnd); + this->uninitialized_copy(From+NumOverwritten, To, OldEnd); return I; } - - const SmallVectorImpl &operator=(const SmallVectorImpl &RHS); - + + const SmallVectorImpl + &operator=(const SmallVectorImpl &RHS); + bool operator==(const SmallVectorImpl &RHS) const { - if (size() != RHS.size()) return false; - return std::equal(begin(), end(), RHS.begin()); + if (this->size() != RHS.size()) return false; + return std::equal(this->begin(), this->end(), RHS.begin()); } - bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); } - + bool operator!=(const SmallVectorImpl &RHS) const { + return !(*this == RHS); + } + bool operator<(const SmallVectorImpl &RHS) const { - return std::lexicographical_compare(begin(), end(), + return std::lexicographical_compare(this->begin(), this->end(), RHS.begin(), RHS.end()); } - + /// set_size - Set the array size to \arg N, which the current array must have /// enough capacity for. /// @@ -421,145 +533,105 @@ public: /// update the size later. This avoids the cost of value initializing elements /// which will only be overwritten. void set_size(unsigned N) { - assert(N <= capacity()); - setEnd(begin() + N); + assert(N <= this->capacity()); + this->setEnd(this->begin() + N); } - + private: - /// 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); - - void construct_range(T *S, T *E, const T &Elt) { + static void construct_range(T *S, T *E, const T &Elt) { for (; S != E; ++S) new (S) T(Elt); } - - 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(); - } - } }; - -// 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(); - size_t CurSize = size(); - size_t NewCapacity = 2*CurCapacity; - if (NewCapacity < MinSize) - NewCapacity = MinSize; - T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T))); - - // Copy the elements over. - if (isPodLike<T>::value) - // Use memcpy for PODs: std::uninitialized_copy optimizes to memmove. - memcpy(NewElts, begin(), CurSize * sizeof(T)); - else - std::uninitialized_copy(begin(), end(), NewElts); - - // Destroy the original elements. - destroy_range(begin(), end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!isSmall()) - operator delete(begin()); - - setEnd(NewElts+CurSize); - BeginX = NewElts; - CapacityX = begin()+NewCapacity; -} + template <typename T> void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) { if (this == &RHS) return; // We can only avoid copying elements if neither vector is small. - if (!isSmall() && !RHS.isSmall()) { - std::swap(BeginX, RHS.BeginX); - std::swap(EndX, RHS.EndX); - std::swap(CapacityX, RHS.CapacityX); + if (!this->isSmall() && !RHS.isSmall()) { + std::swap(this->BeginX, RHS.BeginX); + std::swap(this->EndX, RHS.EndX); + std::swap(this->CapacityX, RHS.CapacityX); return; } - if (RHS.size() > capacity()) - grow(RHS.size()); - if (size() > RHS.capacity()) - RHS.grow(size()); + if (RHS.size() > this->capacity()) + this->grow(RHS.size()); + if (this->size() > RHS.capacity()) + RHS.grow(this->size()); // Swap the shared elements. - size_t NumShared = size(); + size_t NumShared = this->size(); if (NumShared > RHS.size()) NumShared = RHS.size(); for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++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()); + if (this->size() > RHS.size()) { + size_t EltDiff = this->size() - RHS.size(); + this->uninitialized_copy(this->begin()+NumShared, this->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()); - setEnd(end() + EltDiff); - destroy_range(RHS.begin()+NumShared, RHS.end()); + this->destroy_range(this->begin()+NumShared, this->end()); + this->setEnd(this->begin()+NumShared); + } else if (RHS.size() > this->size()) { + size_t EltDiff = RHS.size() - this->size(); + this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); + this->setEnd(this->end() + EltDiff); + this->destroy_range(RHS.begin()+NumShared, RHS.end()); RHS.setEnd(RHS.begin()+NumShared); } } template <typename T> -const SmallVectorImpl<T> & -SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) { +const SmallVectorImpl<T> &SmallVectorImpl<T>:: + operator=(const SmallVectorImpl<T> &RHS) { // Avoid self-assignment. if (this == &RHS) return *this; // If we already have sufficient space, assign the common elements, then // destroy any excess. size_t RHSSize = RHS.size(); - size_t CurSize = size(); + size_t CurSize = this->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, this->begin()); else - NewEnd = begin(); + NewEnd = this->begin(); // Destroy excess elements. - destroy_range(NewEnd, end()); + this->destroy_range(NewEnd, this->end()); // Trim. - setEnd(NewEnd); + this->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 (capacity() < RHSSize) { + if (this->capacity() < RHSSize) { // Destroy current elements. - destroy_range(begin(), end()); - setEnd(begin()); + this->destroy_range(this->begin(), this->end()); + this->setEnd(this->begin()); CurSize = 0; - grow(RHSSize); + this->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, this->begin()); } // Copy construct the new elements in place. - std::uninitialized_copy(RHS.begin()+CurSize, RHS.end(), begin()+CurSize); + this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), + this->begin()+CurSize); // Set end. - setEnd(begin()+RHSSize); + this->setEnd(this->begin()+RHSSize); return *this; } + /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized /// for the case when the array is small. It contains some number of elements /// in-place, which allows it to avoid heap allocation when the actual number of diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index f299f5f..1c73836 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -133,6 +133,22 @@ namespace llvm { /// compare_lower - Compare two strings, ignoring case. int compare_lower(StringRef RHS) const; + /// \brief Determine the edit distance between this string and another + /// string. + /// + /// \param Other the string to compare this string against. + /// + /// \param AllowReplacements whether to allow character + /// replacements (change one character into another) as a single + /// operation, rather than as two operations (an insertion and a + /// removal). + /// + /// \returns the minimum number of character insertions, removals, + /// or (if \p AllowReplacements is \c true) replacements needed to + /// transform one of the given strings into the other. If zero, + /// the strings are identical. + unsigned edit_distance(StringRef Other, bool AllowReplacements = true); + /// str - Get the contents as an std::string. std::string str() const { return std::string(Data, Length); } @@ -159,12 +175,14 @@ namespace llvm { /// startswith - Check if this string starts with the given \arg Prefix. bool startswith(StringRef Prefix) const { - return substr(0, Prefix.Length).equals(Prefix); + return Length >= Prefix.Length && + memcmp(Data, Prefix.Data, Prefix.Length) == 0; } /// endswith - Check if this string ends with the given \arg Suffix. bool endswith(StringRef Suffix) const { - return slice(size() - Suffix.Length, size()).equals(Suffix); + return Length >= Suffix.Length && + memcmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; } /// @} diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 232804e..fdbd9c1 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -17,14 +17,10 @@ #ifndef LLVM_ANALYSIS_DEBUGINFO_H #define LLVM_ANALYSIS_DEBUGINFO_H -#include "llvm/Metadata.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/ValueHandle.h" namespace llvm { class BasicBlock; @@ -42,13 +38,15 @@ namespace llvm { class DebugLoc; struct DebugLocTracker; class Instruction; + class MDNode; class LLVMContext; - /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. This should not - /// be stored in a container, because underly MDNode may change in certain situations. + /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. + /// This should not be stored in a container, because underly MDNode may + /// change in certain situations. class DIDescriptor { protected: - MDNode *DbgNode; + MDNode *DbgNode; /// DIDescriptor constructor. If the specified node is non-null, check /// to make sure that the tag in the descriptor matches 'RequiredTag'. If @@ -86,7 +84,7 @@ namespace llvm { } /// ValidDebugInfo - Return true if N represents valid debug info value. - static bool ValidDebugInfo(MDNode *N, CodeGenOpt::Level OptLevel); + static bool ValidDebugInfo(MDNode *N, unsigned OptLevel); /// dump - print descriptor. void dump() const; @@ -99,6 +97,7 @@ namespace llvm { bool isGlobalVariable() const; bool isScope() const; bool isCompileUnit() const; + bool isNameSpace() const; bool isLexicalBlock() const; bool isSubrange() const; bool isEnumerator() const; @@ -218,7 +217,7 @@ namespace llvm { virtual ~DIType() {} DIDescriptor getContext() const { return getDescriptorField(1); } - StringRef getName() const { return getStringField(2); } + StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); } unsigned getLineNumber() const { return getUnsignedField(4); } uint64_t getSizeInBits() const { return getUInt64Field(5); } @@ -371,20 +370,10 @@ namespace llvm { 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); - } + unsigned getVirtuality() const { return getUnsignedField(11); } + unsigned getVirtualIndex() const { return getUnsignedField(12); } DICompositeType getContainingType() const { - assert (DbgNode->getNumElements() >= 14 && "Invalid type!"); return getFieldAs<DICompositeType>(13); } @@ -442,8 +431,8 @@ namespace llvm { return getNumAddrElements() > 0; } - unsigned getNumAddrElements() const { return DbgNode->getNumElements()-6; } - + unsigned getNumAddrElements() const; + uint64_t getAddrElement(unsigned Idx) const { return getUInt64Field(Idx+6); } @@ -470,6 +459,22 @@ namespace llvm { StringRef getFilename() const { return getContext().getFilename(); } }; + /// DINameSpace - A wrapper for a C++ style name space. + class DINameSpace : public DIScope { + public: + explicit DINameSpace(MDNode *N = 0) : DIScope(N) { + if (DbgNode && !isNameSpace()) + DbgNode = 0; + } + + DIScope getContext() const { return getFieldAs<DIScope>(1); } + StringRef getName() const { return getStringField(2); } + StringRef getDirectory() const { return getContext().getDirectory(); } + StringRef getFilename() const { return getContext().getFilename(); } + DICompileUnit getCompileUnit() const { return getFieldAs<DICompileUnit>(3);} + unsigned getLineNumber() const { return getUnsignedField(4); } + }; + /// DILocation - This object holds location information. This object /// is not associated with any DWARF tag. class DILocation : public DIDescriptor { @@ -624,6 +629,11 @@ namespace llvm { /// with the specified parent context. DILexicalBlock CreateLexicalBlock(DIDescriptor Context); + /// CreateNameSpace - This creates new descriptor for a namespace + /// with the specified parent context. + DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name, + DICompileUnit CU, unsigned LineNo); + /// CreateLocation - Creates a debug info location. DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc); @@ -666,34 +676,9 @@ namespace llvm { /// Find the debug info descriptor corresponding to this global variable. Value *findDbgGlobalDeclare(GlobalVariable *V); -bool getLocationInfo(const Value *V, std::string &DisplayName, - std::string &Type, unsigned &LineNo, std::string &File, - std::string &Dir); - - /// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI, - CodeGenOpt::Level OptLev); - - /// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgFuncStartInst &FSI, - CodeGenOpt::Level OptLev); - - /// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgRegionStartInst &RSI, - CodeGenOpt::Level OptLev); - - /// isValidDebugInfoIntrinsic - Return true if REI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgRegionEndInst &REI, - CodeGenOpt::Level OptLev); - - /// isValidDebugInfoIntrinsic - Return true if DI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI, - CodeGenOpt::Level OptLev); + bool getLocationInfo(const Value *V, std::string &DisplayName, + std::string &Type, unsigned &LineNo, std::string &File, + std::string &Dir); /// ExtractDebugLocation - Extract debug location information /// from llvm.dbg.stoppoint intrinsic. @@ -717,7 +702,6 @@ bool getLocationInfo(const Value *V, std::string &DisplayName, DICompositeType getDICompositeType(DIType T); class DebugInfoFinder { - public: /// processModule - Process entire module and collect debug info /// anchors. diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 2294e53..060286f 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -93,12 +93,28 @@ public: BlockT *getHeader() const { return Blocks.front(); } LoopT *getParentLoop() const { return ParentLoop; } - /// contains - Return true if the specified basic block is in this loop + /// contains - Return true if the specified loop is contained within in + /// this loop. + /// + bool contains(const LoopT *L) const { + if (L == this) return true; + if (L == 0) return false; + return contains(L->getParentLoop()); + } + + /// contains - Return true if the specified basic block is in this loop. /// bool contains(const BlockT *BB) const { return std::find(block_begin(), block_end(), BB) != block_end(); } + /// contains - Return true if the specified instruction is in this loop. + /// + template<class InstT> + bool contains(const InstT *Inst) const { + return contains(Inst->getParent()); + } + /// iterator/begin/end - Return the loops contained entirely within this loop. /// const std::vector<LoopT *> &getSubLoops() const { return SubLoops; } @@ -463,10 +479,6 @@ public: (*I)->print(OS, Depth+2); } - void dump() const { - print(errs()); - } - protected: friend class LoopInfoBase<BlockT, LoopT>; explicit LoopBase(BlockT *BB) : ParentLoop(0) { diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index c04631b..f83cc4f 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -132,21 +132,17 @@ 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 { + /// NonLocalDepResult - This is a result from a NonLocal dependence query. + /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the + /// (potentially phi translated) address that was live in the block. + class NonLocalDepResult { BasicBlock *BB; MemDepResult Result; - WeakVH Address; + Value *Address; public: - NonLocalDepEntry(BasicBlock *bb, MemDepResult result, Value *address) + NonLocalDepResult(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; } @@ -154,7 +150,7 @@ namespace llvm { Result = R; Address = Addr; } - + const MemDepResult &getResult() const { return Result; } /// getAddress - Return the address of this pointer in this block. This can @@ -165,7 +161,27 @@ namespace llvm { /// /// The address is always null for a non-local 'call' dependence. Value *getAddress() const { return Address; } + }; + + /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache. For + /// each BasicBlock (the BB entry) it keeps a MemDepResult. + class NonLocalDepEntry { + BasicBlock *BB; + MemDepResult Result; + public: + NonLocalDepEntry(BasicBlock *bb, MemDepResult result) + : BB(bb), Result(result) {} + + // 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) { Result = R; } + + const MemDepResult &getResult() const { return Result; } + bool operator<(const NonLocalDepEntry &RHS) const { return BB < RHS.BB; } @@ -283,7 +299,7 @@ namespace llvm { /// This method assumes the pointer has a "NonLocal" dependency within BB. void getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *BB, - SmallVectorImpl<NonLocalDepEntry> &Result); + SmallVectorImpl<NonLocalDepResult> &Result); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. @@ -307,7 +323,7 @@ namespace llvm { BasicBlock *BB); bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size, bool isLoad, BasicBlock *BB, - SmallVectorImpl<NonLocalDepEntry> &Result, + SmallVectorImpl<NonLocalDepResult> &Result, DenseMap<BasicBlock*, Value*> &Visited, bool SkipFirstBlock = false); MemDepResult GetNonLocalInfoForBlock(Value *Pointer, uint64_t PointeeSize, diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h index 80ba6d8..300a027 100644 --- a/include/llvm/Analysis/ProfileInfo.h +++ b/include/llvm/Analysis/ProfileInfo.h @@ -38,7 +38,7 @@ namespace llvm { class MachineBasicBlock; class MachineFunction; - // Helper for dumping edges to errs(). + // Helper for dumping edges to dbgs(). 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); @@ -123,7 +123,7 @@ namespace llvm { void setEdgeWeight(Edge e, double w) { DEBUG_WITH_TYPE("profile-info", - errs() << "Creating Edge " << e + dbgs() << "Creating Edge " << e << " (weight: " << format("%.20g",w) << ")\n"); EdgeInformation[getFunction(e)][e] = w; } @@ -170,18 +170,18 @@ namespace llvm { void repair(const FType *F); void dump(FType *F = 0, bool real = true) { - errs() << "**** This is ProfileInfo " << this << " speaking:\n"; + dbgs() << "**** This is ProfileInfo " << this << " speaking:\n"; if (!real) { typename std::set<const FType*> Functions; - errs() << "Functions: \n"; + dbgs() << "Functions: \n"; if (F) { - errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + dbgs() << 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"; + dbgs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n"; Functions.insert(fi->first); } } @@ -190,34 +190,34 @@ namespace llvm { FI != FE; ++FI) { const FType *F = *FI; typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F); - errs() << "BasicBlocks for Function " << F << ":\n"; + dbgs() << "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"; + dbgs() << 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"; + dbgs() << "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"; + dbgs() << 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"; + dbgs() << "Functions: \n"; + dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; - errs() << "BasicBlocks for Function " << F << ":\n"; + dbgs() << "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"; + dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n"; } } - errs() << "**** ProfileInfo " << this << ", over and out.\n"; + dbgs() << "**** ProfileInfo " << this << ", over and out.\n"; } bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 4aa3dfa..6f57c74 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -243,7 +243,7 @@ namespace llvm { /// createNodeForGEP - Provide the special handling we need to analyze GEP /// SCEVs. - const SCEV *createNodeForGEP(Operator *GEP); + const SCEV *createNodeForGEP(GEPOperator *GEP); /// computeSCEVAtScope - Implementation code for getSCEVAtScope; called /// at most once for each SCEV+Loop pair. diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h index 677d41d..c3c2f4b 100644 --- a/include/llvm/Analysis/SparsePropagation.h +++ b/include/llvm/Analysis/SparsePropagation.h @@ -30,7 +30,6 @@ namespace llvm { class BasicBlock; class Function; class SparseSolver; - class LLVMContext; class raw_ostream; template<typename T> class SmallVectorImpl; @@ -120,8 +119,6 @@ class SparseSolver { /// compute transfer functions. AbstractLatticeFunction *LatticeFunc; - LLVMContext *Context; - DenseMap<Value*, LatticeVal> ValueState; // The state each value is in. SmallPtrSet<BasicBlock*, 16> BBExecutable; // The bbs that are executable. @@ -137,8 +134,8 @@ class SparseSolver { SparseSolver(const SparseSolver&); // DO NOT IMPLEMENT void operator=(const SparseSolver&); // DO NOT IMPLEMENT public: - explicit SparseSolver(AbstractLatticeFunction *Lattice, LLVMContext *C) - : LatticeFunc(Lattice), Context(C) {} + explicit SparseSolver(AbstractLatticeFunction *Lattice) + : LatticeFunc(Lattice) {} ~SparseSolver() { delete LatticeFunc; } diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 5f3c671..7c673c3 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -24,7 +24,6 @@ namespace llvm { class Instruction; class APInt; class TargetData; - class LLVMContext; /// ComputeMaskedBits - Determine which of the bits specified in Mask are /// known to be either zero or one and return them in the KnownZero/KnownOne diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index ca54f48..71c001f 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -17,6 +17,7 @@ #include "llvm/Value.h" #include "llvm/Attributes.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 80d8702..e358f91 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -17,6 +17,7 @@ #include "llvm/Instruction.h" #include "llvm/SymbolTableListTraits.h" #include "llvm/ADT/ilist.h" +#include "llvm/ADT/Twine.h" #include "llvm/System/DataTypes.h" namespace llvm { @@ -239,15 +240,21 @@ public: /// hasAddressTaken - returns true if there are any uses of this basic block /// other than direct branches, switches, etc. to it. - bool hasAddressTaken() const { return SubclassData != 0; } + bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but /// almost never 2, and inconceivably 3 or more. void AdjustBlockAddressRefCount(int Amt) { - SubclassData += Amt; - assert((int)(signed char)SubclassData >= 0 && "Refcount wrap-around"); + setValueSubclassData(getSubclassDataFromValue()+Amt); + assert((int)(signed char)getSubclassDataFromValue() >= 0 && + "Refcount wrap-around"); + } + // Shadow Value::setValueSubclassData with a private forwarding method so that + // any future subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); } }; diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h deleted file mode 100644 index 3266038..0000000 --- a/include/llvm/Bitcode/Deserialize.h +++ /dev/null @@ -1,516 +0,0 @@ -//=- Deserialize.h - Generic Object Deserialization from Bitcode --*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface for generic object deserialization from -// LLVM bitcode. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BITCODE_SERIALIZE_INPUT -#define LLVM_BITCODE_SERIALIZE_INPUT - -#include "llvm/Bitcode/BitstreamReader.h" -#include "llvm/Bitcode/Serialization.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Allocator.h" -#include "llvm/System/DataTypes.h" -#include <vector> - -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. - //===----------------------------------------------------------===// - - - typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy; - - //===----------------------------------------------------------===// - // Publicly visible types. - //===----------------------------------------------------------===// - -public: - struct Location { - uint64_t BitNo; - unsigned BlockID; - unsigned NumWords; - - Location(uint64_t bit, unsigned bid, unsigned words) - : BitNo(bit), BlockID(bid), NumWords(words) {} - - Location() : BitNo(0), BlockID(0), NumWords(0) {} - - Location& operator=(Location& RHS) { - BitNo = RHS.BitNo; - BlockID = RHS.BlockID; - NumWords = RHS.NumWords; - return *this; - } - - bool operator==(const Location& RHS) const { return BitNo == RHS.BitNo; } - bool operator!=(const Location& RHS) const { return BitNo != RHS.BitNo; } - - bool contains(const Location& RHS) const { - if (RHS.BitNo < BitNo) - return false; - - if ((RHS.BitNo - BitNo) >> 5 < NumWords) - return true; - - return false; - } - }; - - //===----------------------------------------------------------===// - // Internal data members. - //===----------------------------------------------------------===// - -private: - BitstreamCursor Stream; - SmallVector<uint64_t,20> Record; - unsigned RecIdx; - BumpPtrAllocator Allocator; - BPNode* FreeList; - MapTy BPatchMap; - llvm::SmallVector<Location,8> BlockStack; - unsigned AbbrevNo; - unsigned RecordCode; - uint64_t StreamStart; - - //===----------------------------------------------------------===// - // Public Interface. - //===----------------------------------------------------------===// - -public: - Deserializer(BitstreamReader& stream); - ~Deserializer(); - - uint64_t ReadInt(); - int64_t ReadSInt(); - SerializedPtrID ReadPtrID() { return (SerializedPtrID) ReadInt(); } - - - bool ReadBool() { - return ReadInt() ? true : false; - } - - template <typename T> - inline T& Read(T& X) { - SerializeTrait<T>::Read(*this,X); - return X; - } - - template <typename T> - inline T* Create() { - return SerializeTrait<T>::Create(*this); - } - - char* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); - void ReadCStr(std::vector<char>& buff, bool isNullTerm=false, unsigned Idx=0); - - template <typename T> - inline T* ReadOwnedPtr(bool AutoRegister = true) { - SerializedPtrID PtrID = ReadPtrID(); - - if (!PtrID) - return NULL; - - T* x = SerializeTrait<T>::Create(*this); - - if (AutoRegister) - RegisterPtr(PtrID,x); - - return x; - } - - template <typename T, typename Arg1> - inline T* ReadOwnedPtr(Arg1& arg1, bool AutoRegister = true) { - SerializedPtrID PtrID = ReadPtrID(); - - if (!PtrID) - return NULL; - - T* x = SerializeTrait<T>::Create(*this, arg1); - - if (AutoRegister) - RegisterPtr(PtrID,x); - - return x; - } - - template <typename T> - inline void ReadOwnedPtr(T*& Ptr, bool AutoRegister = true) { - Ptr = ReadOwnedPtr<T>(AutoRegister); - } - - template <typename T1, typename T2> - void BatchReadOwnedPtrs(T1*& P1, T2*& P2, - bool A1=true, bool A2=true) { - - SerializedPtrID ID1 = ReadPtrID(); - SerializedPtrID ID2 = ReadPtrID(); - - P1 = (ID1) ? SerializeTrait<T1>::Create(*this) : NULL; - if (ID1 && A1) RegisterPtr(ID1,P1); - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - } - - template <typename T1, typename T2, typename Arg1> - void BatchReadOwnedPtrs(T1*& P1, T2*& P2, Arg1& arg1, - bool A1=true, bool A2=true) { - - SerializedPtrID ID1 = ReadPtrID(); - SerializedPtrID ID2 = ReadPtrID(); - - P1 = (ID1) ? SerializeTrait<T1>::Create(*this, arg1) : NULL; - if (ID1 && A1) RegisterPtr(ID1,P1); - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - } - - template <typename T1, typename T2, typename T3> - void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3, - bool A1=true, bool A2=true, bool A3=true) { - - SerializedPtrID ID1 = ReadPtrID(); - SerializedPtrID ID2 = ReadPtrID(); - SerializedPtrID ID3 = ReadPtrID(); - - P1 = (ID1) ? SerializeTrait<T1>::Create(*this) : NULL; - if (ID1 && A1) RegisterPtr(ID1,P1); - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - - P3 = (ID3) ? SerializeTrait<T3>::Create(*this) : NULL; - if (ID3 && A3) RegisterPtr(ID3,P3); - } - - template <typename T1, typename T2, typename T3, typename Arg1> - void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3, Arg1& arg1, - bool A1=true, bool A2=true, bool A3=true) { - - SerializedPtrID ID1 = ReadPtrID(); - SerializedPtrID ID2 = ReadPtrID(); - SerializedPtrID ID3 = ReadPtrID(); - - P1 = (ID1) ? SerializeTrait<T1>::Create(*this, arg1) : NULL; - if (ID1 && A1) RegisterPtr(ID1,P1); - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - - P3 = (ID3) ? SerializeTrait<T3>::Create(*this, arg1) : NULL; - if (ID3 && A3) RegisterPtr(ID3,P3); - } - - template <typename T> - void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) { - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumPtrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - for (unsigned i = 0; i < NumPtrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T* p = PtrID ? SerializeTrait<T>::Create(*this) : NULL; - - if (PtrID && AutoRegister) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - } - - template <typename T, typename Arg1> - void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, Arg1& arg1, - bool AutoRegister=true) { - - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumPtrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - for (unsigned i = 0; i < NumPtrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T* p = PtrID ? SerializeTrait<T>::Create(*this, arg1) : NULL; - - if (PtrID && AutoRegister) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - } - - template <typename T1, typename T2> - void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, T2*& P2, - bool A1=true, bool A2=true) { - - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - SerializedPtrID ID2 = ReadPtrID(); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T1* p = PtrID ? SerializeTrait<T1>::Create(*this) : NULL; - - if (PtrID && A1) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - } - - template <typename T1, typename T2, typename Arg1> - void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, T2*& P2, Arg1& arg1, - bool A1=true, bool A2=true) { - - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - SerializedPtrID ID2 = ReadPtrID(); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T1* p = PtrID ? SerializeTrait<T1>::Create(*this, arg1) : NULL; - - if (PtrID && A1) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - } - - template <typename T1, typename T2, typename T3> - void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, - T2*& P2, T3*& P3, - bool A1=true, bool A2=true, bool A3=true) { - - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - SerializedPtrID ID2 = ReadPtrID(); - SerializedPtrID ID3 = ReadPtrID(); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T1* p = PtrID ? SerializeTrait<T1>::Create(*this) : NULL; - - if (PtrID && A1) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - - P3 = (ID3) ? SerializeTrait<T3>::Create(*this) : NULL; - if (ID3 && A3) RegisterPtr(ID3,P3); - } - - template <typename T1, typename T2, typename T3, typename Arg1> - void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, - T2*& P2, T3*& P3, Arg1& arg1, - bool A1=true, bool A2=true, bool A3=true) { - - llvm::SmallVector<SerializedPtrID,10> BatchIDVec; - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - BatchIDVec.push_back(ReadPtrID()); - - SerializedPtrID ID2 = ReadPtrID(); - SerializedPtrID ID3 = ReadPtrID(); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) { - SerializedPtrID& PtrID = BatchIDVec[i]; - - T1* p = PtrID ? SerializeTrait<T1>::Create(*this, arg1) : NULL; - - if (PtrID && A1) - RegisterPtr(PtrID,p); - - Ptrs[i] = p; - } - - P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL; - if (ID2 && A2) RegisterPtr(ID2,P2); - - P3 = (ID3) ? SerializeTrait<T3>::Create(*this, arg1) : NULL; - if (ID3 && A3) RegisterPtr(ID3,P3); - } - - template <typename T> - void ReadPtr(T*& PtrRef, bool AllowBackpatch = true) { - ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef), AllowBackpatch); - } - - template <typename T> - void ReadPtr(const T*& PtrRef, bool AllowBackpatch = true) { - ReadPtr(const_cast<T*&>(PtrRef), AllowBackpatch); - } - - - template <typename T> - void ReadPtr(T*& PtrRef, const SerializedPtrID& PtrID, - bool AllowBackpatch = true) { - ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef), PtrID, AllowBackpatch); - } - - template <typename T> - void ReadPtr(const T*& PtrRef, const SerializedPtrID& PtrID, - bool AllowBackpatch = true) { - - ReadPtr(const_cast<T*&>(PtrRef), PtrID, AllowBackpatch); - } - - template <typename T> - T* ReadPtr() { T* x = 0; ReadPtr<T>(x,false); return x; } - - void ReadUIntPtr(uintptr_t& PtrRef, const SerializedPtrID& PtrID, - bool AllowBackpatch = true); - - void ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch = true) { - ReadUIntPtr(PtrRef,ReadPtrID(),AllowBackpatch); - } - - template <typename T> - T& ReadRef() { - T* p = reinterpret_cast<T*>(ReadInternalRefPtr()); - return *p; - } - - void RegisterPtr(const SerializedPtrID& PtrID, const void* Ptr); - - void RegisterPtr(const void* Ptr) { - RegisterPtr(ReadPtrID(),Ptr); - } - - template<typename T> - void RegisterRef(const T& x) { - RegisterPtr(&x); - } - - template<typename T> - void RegisterRef(const SerializedPtrID& PtrID, const T& x) { - RegisterPtr(PtrID,&x); - } - - Location getCurrentBlockLocation(); - unsigned getCurrentBlockID(); - unsigned getAbbrevNo(); - - bool FinishedBlock(Location BlockLoc); - bool JumpTo(const Location& BlockLoc); - void Rewind(); - - bool AtEnd(); - bool inRecord(); - void SkipBlock(); - bool SkipToBlock(unsigned BlockID); - - unsigned getRecordCode(); - - BitstreamCursor &getStream() { return Stream; } - -private: - bool AdvanceStream(); - void ReadRecord(); - - uintptr_t ReadInternalRefPtr(); - - static inline bool HasFinalPtr(MapTy::value_type& V) { - return V.first.hasFinalPtr(); - } - - static inline uintptr_t GetFinalPtr(MapTy::value_type& V) { - return reinterpret_cast<uintptr_t>(V.second.Ptr); - } - - static inline BPNode* GetBPNode(MapTy::value_type& V) { - return V.second.Head; - } - - static inline void SetBPNode(MapTy::value_type& V, BPNode* N) { - V.second.Head = N; - } - - void SetPtr(MapTy::value_type& V, const void* P) { - V.first.MarkFinal(); - V.second.SetPtr(FreeList,const_cast<void*>(P)); - } -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/Bitcode/Serialization.h b/include/llvm/Bitcode/Serialization.h deleted file mode 100644 index 2f0d350..0000000 --- a/include/llvm/Bitcode/Serialization.h +++ /dev/null @@ -1,68 +0,0 @@ -//==- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines traits for primitive types used for both object -// serialization and deserialization. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BITCODE_SERIALIZE -#define LLVM_BITCODE_SERIALIZE - -#include "llvm/Bitcode/SerializationFwd.h" - -namespace llvm { - -/// SerializeTrait - SerializeTrait bridges between the Serializer/Deserializer -/// and the functions that serialize objects of specific types. The default -/// behavior is to call static methods of the class for the object being -/// serialized, but this behavior can be changed by specializing this -/// template. Classes only need to implement the methods corresponding -/// to the serialization scheme they want to support. For example, "Read" -/// and "ReadVal" correspond to different deserialization schemes which make -/// sense for different types; a class need only implement one of them. -/// Serialization and deserialization of pointers are specially handled -/// by the Serializer and Deserializer using the EmitOwnedPtr, etc. methods. -/// To serialize the actual object referred to by a pointer, the class -/// of the object either must implement the methods called by the default -/// behavior of SerializeTrait, or specialize SerializeTrait. This latter -/// is useful when one cannot add methods to an existing class (for example). -template <typename T> -struct SerializeTrait { - static inline void Emit(Serializer& S, const T& X) { X.Emit(S); } - static inline void Read(Deserializer& D, T& X) { X.Read(D); } - static inline T* Create(Deserializer& D) { return T::Create(D); } - - template <typename Arg1> - static inline T* Create(Deserializer& D, Arg1& arg1) { - return T::Create(D, arg1); - } -}; - -#define SERIALIZE_INT_TRAIT(TYPE)\ -template <> struct SerializeTrait<TYPE> {\ - static void Emit(Serializer& S, TYPE X);\ - static void Read(Deserializer& S, TYPE& X); }; - -SERIALIZE_INT_TRAIT(bool) -SERIALIZE_INT_TRAIT(unsigned char) -SERIALIZE_INT_TRAIT(unsigned short) -SERIALIZE_INT_TRAIT(unsigned int) -SERIALIZE_INT_TRAIT(unsigned long) - -SERIALIZE_INT_TRAIT(signed char) -SERIALIZE_INT_TRAIT(signed short) -SERIALIZE_INT_TRAIT(signed int) -SERIALIZE_INT_TRAIT(signed long) - -#undef SERIALIZE_INT_TRAIT - -} // end namespace llvm - -#endif diff --git a/include/llvm/Bitcode/SerializationFwd.h b/include/llvm/Bitcode/SerializationFwd.h deleted file mode 100644 index 7224190..0000000 --- a/include/llvm/Bitcode/SerializationFwd.h +++ /dev/null @@ -1,27 +0,0 @@ -//==- SerializationFwd.h - Forward references for Serialization ---*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides forward references for bitcode object serialization. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BITCODE_SERIALIZE_FWD -#define LLVM_BITCODE_SERIALIZE_FWD - -namespace llvm { - -class Serializer; -class Deserializer; -template <typename T> struct SerializeTrait; - -typedef unsigned SerializedPtrID; - -} // end namespace llvm - -#endif diff --git a/include/llvm/Bitcode/Serialize.h b/include/llvm/Bitcode/Serialize.h deleted file mode 100644 index 6fe4f02..0000000 --- a/include/llvm/Bitcode/Serialize.h +++ /dev/null @@ -1,211 +0,0 @@ -//==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface for generic object serialization to -// LLVM bitcode. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BITCODE_SERIALIZE_OUTPUT -#define LLVM_BITCODE_SERIALIZE_OUTPUT - -#include "llvm/Bitcode/Serialization.h" -#include "llvm/Bitcode/BitstreamWriter.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/DenseMap.h" - -namespace llvm { - -class Serializer { - BitstreamWriter& Stream; - SmallVector<uint64_t,10> Record; - unsigned BlockLevel; - - typedef DenseMap<const void*,unsigned> MapTy; - MapTy PtrMap; - -public: - explicit Serializer(BitstreamWriter& stream); - ~Serializer(); - - //==------------------------------------------------==// - // Template-based dispatch to emit arbitrary types. - //==------------------------------------------------==// - - template <typename T> - inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); } - - //==------------------------------------------------==// - // Methods to emit primitive types. - //==------------------------------------------------==// - - void EmitInt(uint64_t X); - void EmitSInt(int64_t X); - - inline void EmitBool(bool X) { EmitInt(X); } - void EmitCStr(const char* beg, const char* end); - void EmitCStr(const char* cstr); - - void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); } - - template <typename T> - inline void EmitRef(const T& ref) { EmitPtr(&ref); } - - // Emit a pointer and the object pointed to. (This has no relation to the - // OwningPtr<> class.) - template <typename T> - inline void EmitOwnedPtr(T* ptr) { - EmitPtr(ptr); - if (ptr) SerializeTrait<T>::Emit(*this,*ptr); - } - - - //==------------------------------------------------==// - // Batch emission of pointers. - //==------------------------------------------------==// - - template <typename T1, typename T2> - void BatchEmitOwnedPtrs(T1* p1, T2* p2) { - EmitPtr(p1); - EmitPtr(p2); - if (p1) SerializeTrait<T1>::Emit(*this,*p1); - if (p2) SerializeTrait<T2>::Emit(*this,*p2); - } - - template <typename T1, typename T2, typename T3> - void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) { - EmitPtr(p1); - EmitPtr(p2); - EmitPtr(p3); - if (p1) SerializeTrait<T1>::Emit(*this,*p1); - if (p2) SerializeTrait<T2>::Emit(*this,*p2); - if (p3) SerializeTrait<T3>::Emit(*this,*p3); - } - - template <typename T1, typename T2, typename T3, typename T4> - void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) { - EmitPtr(p1); - EmitPtr(p2); - EmitPtr(p3); - EmitPtr(p4); - if (p1) SerializeTrait<T1>::Emit(*this,*p1); - if (p2) SerializeTrait<T2>::Emit(*this,*p2); - if (p3) SerializeTrait<T3>::Emit(*this,*p3); - if (p4) SerializeTrait<T4>::Emit(*this,*p4); - } - - template <typename T> - void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) { - for (unsigned i = 0; i < NumPtrs; ++i) - EmitPtr(Ptrs[i]); - - for (unsigned i = 0; i < NumPtrs; ++i) - if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]); - } - - template <typename T1, typename T2> - void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) { - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - EmitPtr(Ptrs[i]); - - EmitPtr(p2); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); - - if (p2) SerializeTrait<T2>::Emit(*this,*p2); - } - - template <typename T1, typename T2, typename T3> - void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, - T2* p2, T3* p3) { - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - EmitPtr(Ptrs[i]); - - EmitPtr(p2); - EmitPtr(p3); - - for (unsigned i = 0; i < NumT1Ptrs; ++i) - if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); - - if (p2) SerializeTrait<T2>::Emit(*this,*p2); - if (p3) SerializeTrait<T3>::Emit(*this,*p3); - } - - //==------------------------------------------------==// - // Emitter Functors - //==------------------------------------------------==// - - template <typename T> - struct Emitter0 { - Serializer& S; - Emitter0(Serializer& s) : S(s) {} - void operator()(const T& x) const { - SerializeTrait<T>::Emit(S,x); - } - }; - - template <typename T, typename Arg1> - struct Emitter1 { - Serializer& S; - Arg1 A1; - - Emitter1(Serializer& s, Arg1 a1) : S(s), A1(a1) {} - void operator()(const T& x) const { - SerializeTrait<T>::Emit(S,x,A1); - } - }; - - template <typename T, typename Arg1, typename Arg2> - struct Emitter2 { - Serializer& S; - Arg1 A1; - Arg2 A2; - - Emitter2(Serializer& s, Arg1 a1, Arg2 a2) : S(s), A1(a1), A2(a2) {} - void operator()(const T& x) const { - SerializeTrait<T>::Emit(S,x,A1,A2); - } - }; - - template <typename T> - Emitter0<T> MakeEmitter() { - return Emitter0<T>(*this); - } - - template <typename T, typename Arg1> - Emitter1<T,Arg1> MakeEmitter(Arg1 a1) { - return Emitter1<T,Arg1>(*this,a1); - } - - template <typename T, typename Arg1, typename Arg2> - Emitter2<T,Arg1,Arg2> MakeEmitter(Arg1 a1, Arg2 a2) { - return Emitter2<T,Arg1,Arg2>(*this,a1,a2); - } - - //==------------------------------------------------==// - // Misc. query and block/record manipulation methods. - //==------------------------------------------------==// - - bool isRegistered(const void* p) const; - - void FlushRecord() { if (inRecord()) EmitRecord(); } - void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3); - void ExitBlock(); - -private: - void EmitRecord(); - inline bool inRecord() { return Record.size() > 0; } - SerializedPtrID getPtrId(const void* ptr); -}; - -} // end namespace llvm -#endif diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index ea3e59b..9c4e5b9 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -68,29 +68,11 @@ public: /// virtual bool finishFunction(MachineFunction &F) = 0; - /// startGVStub - This callback is invoked when the JIT needs the address of a - /// GV (e.g. function) that has not been code generated yet. The StubSize - /// specifies the total size required by the stub. The BufferState must be - /// passed to finishGVStub, and start/finish pairs with the same BufferState - /// must be properly nested. - /// - virtual void startGVStub(BufferState &BS, const GlobalValue* GV, - unsigned StubSize, unsigned Alignment = 1) = 0; - - /// startGVStub - This callback is invoked when the JIT needs the address of a - /// GV (e.g. function) that has not been code generated yet. Buffer points to - /// memory already allocated for this stub. The BufferState must be passed to - /// finishGVStub, and start/finish pairs with the same BufferState must be - /// properly nested. - /// - virtual void startGVStub(BufferState &BS, void *Buffer, - unsigned StubSize) = 0; - - /// finishGVStub - This callback is invoked to terminate a GV stub and returns - /// the start address of the stub. The BufferState must first have been - /// passed to startGVStub. - /// - virtual void *finishGVStub(BufferState &BS) = 0; + /// allocIndirectGV - Allocates and fills storage for an indirect + /// GlobalValue, and returns the address. + virtual void *allocIndirectGV(const GlobalValue *GV, + const uint8_t *Buffer, size_t Size, + unsigned Alignment) = 0; /// emitByte - This callback is invoked when a byte needs to be written to the /// output stream. diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 791db00..d598a93 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -48,41 +48,16 @@ class Function; /// occurred, more memory is allocated, and we reemit the code into it. /// class MachineCodeEmitter { -public: - class BufferState { - friend class MachineCodeEmitter; - /// BufferBegin/BufferEnd - Pointers to the start and end of the memory - /// allocated for this code buffer. - uint8_t *BufferBegin, *BufferEnd; - - /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting - /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If - /// this pointer is at BufferEnd, it will never move due to code emission, - /// and all code emission requests will be ignored (this is the buffer - /// overflow condition). - uint8_t *CurBufferPtr; - public: - BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {} - }; - protected: - /// These have the same meanings as the fields in BufferState - uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr; - - /// Save or restore the current buffer state. The BufferState objects must be - /// used as a stack. - void SaveStateTo(BufferState &BS) { - assert(BS.BufferBegin == NULL && - "Can't save state into the same BufferState twice."); - BS.BufferBegin = BufferBegin; - BS.BufferEnd = BufferEnd; - BS.CurBufferPtr = CurBufferPtr; - } - void RestoreStateFrom(BufferState &BS) { - BufferBegin = BS.BufferBegin; - BufferEnd = BS.BufferEnd; - CurBufferPtr = BS.CurBufferPtr; - } + /// BufferBegin/BufferEnd - Pointers to the start and end of the memory + /// allocated for this code buffer. + uint8_t *BufferBegin, *BufferEnd; + /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting + /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If + /// this pointer is at BufferEnd, it will never move due to code emission, and + /// all code emission requests will be ignored (this is the buffer overflow + /// condition). + uint8_t *CurBufferPtr; public: virtual ~MachineCodeEmitter() {} @@ -113,15 +88,23 @@ public: /// void emitWordLE(uint32_t W) { if (4 <= BufferEnd-CurBufferPtr) { - *CurBufferPtr++ = (uint8_t)(W >> 0); - *CurBufferPtr++ = (uint8_t)(W >> 8); - *CurBufferPtr++ = (uint8_t)(W >> 16); - *CurBufferPtr++ = (uint8_t)(W >> 24); + emitWordLEInto(CurBufferPtr, W); } else { CurBufferPtr = BufferEnd; } } - + + /// emitWordLEInto - This callback is invoked when a 32-bit word needs to be + /// written to an arbitrary buffer in little-endian format. Buf must have at + /// least 4 bytes of available space. + /// + static void emitWordLEInto(uint8_t *&Buf, uint32_t W) { + *Buf++ = (uint8_t)(W >> 0); + *Buf++ = (uint8_t)(W >> 8); + *Buf++ = (uint8_t)(W >> 16); + *Buf++ = (uint8_t)(W >> 24); + } + /// emitWordBE - This callback is invoked when a 32-bit word needs to be /// written to the output stream in big-endian format. /// diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index bac9fce..e9b645b 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -43,6 +43,7 @@ #include "llvm/GlobalValue.h" #include "llvm/Pass.h" #include "llvm/Metadata.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index 680d2b8..6ee2e90 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -129,9 +129,9 @@ public: // Add existing passes to option. for (RegistryClass *Node = RegistryClass::getList(); Node; Node = Node->getNext()) { - addLiteralOption(Node->getName(), + this->addLiteralOption(Node->getName(), (typename RegistryClass::FunctionPassCtor)Node->getCtor(), - Node->getDescription()); + Node->getDescription()); } // Make sure we listen for list changes. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index c09c634..d55dd7f 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -29,12 +29,13 @@ namespace llvm { class AliasAnalysis; -class TargetLowering; -class MachineModuleInfo; class DwarfWriter; -class MachineFunction; -class MachineConstantPoolValue; class FunctionLoweringInfo; +class MachineConstantPoolValue; +class MachineFunction; +class MachineModuleInfo; +class SDNodeOrdering; +class TargetLowering; template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> { private: @@ -110,45 +111,9 @@ 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; + /// SDNodeOrdering - The ordering of the SDNodes. It roughly corresponds to + /// the ordering of the original LLVM instructions. + SDNodeOrdering *Ordering; /// VerifyNode - Sanity check the given node. Aborts if it is invalid. void VerifyNode(SDNode *N); @@ -242,13 +207,6 @@ 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 @@ -873,6 +831,12 @@ public: } } + /// AssignOrdering - Assign an order to the SDNode. + void AssignOrdering(SDNode *SD, unsigned Order); + + /// GetOrdering - Get the order for the SDNode. + unsigned GetOrdering(const SDNode *SD) const; + void dump() const; /// CreateStackTemporary - Create a stack temporary, suitable for holding the diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 571db47..7b1931a 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -414,12 +414,13 @@ namespace ISD { /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type. FP_EXTEND, - // BIT_CONVERT - Theis operator converts between integer and FP values, as - // if one was stored to memory as integer and the other was loaded from the - // same address (or equivalently for vector format conversions, etc). The - // source and result are required to have the same bit size (e.g. - // f32 <-> i32). This can also be used for int-to-int or fp-to-fp - // conversions, but that is a noop, deleted by getNode(). + // BIT_CONVERT - This operator converts between integer, vector and FP + // values, as if the value was stored to memory with one type and loaded + // from the same address with the other type (or equivalently for vector + // format conversions, etc). The source and result are required to have + // the same bit size (e.g. f32 <-> i32). This can also be used for + // int-to-int or fp-to-fp conversions, but that is a noop, deleted by + // getNode(). BIT_CONVERT, // CONVERT_RNDSAT - This operator is used to support various conversions @@ -1227,7 +1228,7 @@ public: SDVTList getVTList() const { SDVTList X = { ValueList, NumValues }; return X; - }; + } /// getFlaggedNode - If this node has a flag operand, return the node /// to which the flag operand points. Otherwise return NULL. diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 9a85ee1..163642a 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -176,7 +176,7 @@ namespace llvm { // Construct a new slot index from the given one, set the phi flag on the // new index to the value of the phi parameter. SlotIndex(const SlotIndex &li, bool phi) - : lie(&li.entry(), phi ? PHI_BIT & li.getSlot() : (unsigned)li.getSlot()){ + : lie(&li.entry(), phi ? PHI_BIT | li.getSlot() : (unsigned)li.getSlot()){ assert(lie.getPointer() != 0 && "Attempt to construct index with 0 pointer."); } @@ -184,7 +184,7 @@ namespace llvm { // Construct a new slot index from the given one, set the phi flag on the // new index to the value of the phi parameter, and the slot to the new slot. SlotIndex(const SlotIndex &li, bool phi, Slot s) - : lie(&li.entry(), phi ? PHI_BIT & s : (unsigned)s) { + : lie(&li.entry(), phi ? PHI_BIT | s : (unsigned)s) { assert(lie.getPointer() != 0 && "Attempt to construct index with 0 pointer."); } @@ -579,7 +579,7 @@ namespace llvm { (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; assert(J != idx2MBBMap.end() && J->first <= index && - index <= getMBBEndIdx(J->second) && + index < getMBBEndIdx(J->second) && "index does not correspond to an MBB"); return J->second; } diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 06e07f3..9dc4c7b 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -589,7 +589,25 @@ namespace llvm { return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth)); } - /// isPow2VectorType - Retuns true if the given vector is a power of 2. + /// getHalfSizedIntegerVT - Finds the smallest simple value type that is + /// greater than or equal to half the width of this EVT. If no simple + /// value type can be found, an extended integer value type of half the + /// size (rounded up) is returned. + EVT getHalfSizedIntegerVT(LLVMContext &Context) const { + assert(isInteger() && !isVector() && "Invalid integer type!"); + unsigned EVTSize = getSizeInBits(); + for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; + IntVT <= MVT::LAST_INTEGER_VALUETYPE; + ++IntVT) { + EVT HalfVT = EVT((MVT::SimpleValueType)IntVT); + if(HalfVT.getSizeInBits() * 2 >= EVTSize) { + return HalfVT; + } + } + return getIntegerVT(Context, (EVTSize + 1) / 2); + } + + /// isPow2VectorType - Returns true if the given vector is a power of 2. bool isPow2VectorType() const { unsigned NElts = getVectorNumElements(); return !(NElts & (NElts - 1)); diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 8d2f63b..9c3e861 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -84,6 +84,7 @@ def stop_compilation; def unpack_values; def warning; def error; +def set_option; def unset_option; // Increase/decrease the edge weight. diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index caa13f6..f34f9cb 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -605,7 +605,7 @@ protected: ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps) : Constant(ty, ConstantExprVal, Ops, NumOps) { // Operation type (an Instruction opcode) is stored as the SubclassData. - SubclassData = Opcode; + setValueSubclassData(Opcode); } // These private methods are used by the type resolution code to create @@ -692,8 +692,10 @@ public: static Constant *getIntToPtr(Constant *C, const Type *Ty); static Constant *getBitCast (Constant *C, const Type *Ty); + static Constant *getNSWNeg(Constant *C); static Constant *getNSWAdd(Constant *C1, Constant *C2); static Constant *getNSWSub(Constant *C1, Constant *C2); + static Constant *getNSWMul(Constant *C1, Constant *C2); static Constant *getExactSDiv(Constant *C1, Constant *C2); /// Transparently provide more efficient getOperand methods. @@ -812,7 +814,7 @@ public: virtual bool isNullValue() const { return false; } /// getOpcode - Return the opcode at the root of this constant expression - unsigned getOpcode() const { return SubclassData; } + unsigned getOpcode() const { return getSubclassDataFromValue(); } /// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is /// not an ICMP or FCMP constant expression. @@ -845,6 +847,13 @@ public: static inline bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; } + +private: + // Shadow Value::setValueSubclassData with a private forwarding method so that + // subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } }; template <> diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index fb51430..c220608 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -502,9 +502,7 @@ class OpaqueType : public DerivedType { public: /// OpaqueType::get - Static factory method for the OpaqueType class... /// - static OpaqueType *get(LLVMContext &C) { - return new OpaqueType(C); // All opaque types are distinct - } + static OpaqueType *get(LLVMContext &C); // Implement support for type inquiry through isa, cast, and dyn_cast: static inline bool classof(const OpaqueType *) { return true; } diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 64be545..3882233 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -87,6 +87,9 @@ private: ValueSymbolTable *SymTab; ///< Symbol table of args/instructions AttrListPtr AttributeList; ///< Parameter attributes + // HasLazyArguments is stored in Value::SubclassData. + /*bool HasLazyArguments;*/ + // The Calling Convention is stored in Value::SubclassData. /*CallingConv::ID CallingConvention;*/ @@ -99,7 +102,7 @@ private: /// needs it. The hasLazyArguments predicate returns true if the arg list /// hasn't been set up yet. bool hasLazyArguments() const { - return SubclassData & 1; + return getSubclassDataFromValue() & 1; } void CheckLazyArguments() const { if (hasLazyArguments()) @@ -156,10 +159,11 @@ public: /// calling convention of this function. The enum values for the known /// calling conventions are defined in CallingConv.h. CallingConv::ID getCallingConv() const { - return static_cast<CallingConv::ID>(SubclassData >> 1); + return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1); } void setCallingConv(CallingConv::ID CC) { - SubclassData = (SubclassData & 1) | (static_cast<unsigned>(CC) << 1); + setValueSubclassData((getSubclassDataFromValue() & 1) | + (static_cast<unsigned>(CC) << 1)); } /// getAttributes - Return the attribute list for this Function. @@ -407,6 +411,12 @@ public: /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool hasAddressTaken() const; +private: + // Shadow Value::setValueSubclassData with a private forwarding method so that + // subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } }; inline ValueSymbolTable * diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index 9b3f450..9867c51 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -18,6 +18,7 @@ #include "llvm/GlobalValue.h" #include "llvm/OperandTraits.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index b8d219c..9875a83 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -56,7 +56,7 @@ public: protected: GlobalValue(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps, - LinkageTypes linkage, const Twine &Name = "") + LinkageTypes linkage, const Twine &Name) : Constant(ty, vty, Ops, NumOps), Parent(0), Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) { setName(Name); diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 68bd1b3..633e8b4 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -23,6 +23,7 @@ #include "llvm/GlobalValue.h" #include "llvm/OperandTraits.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index bc89969..85aaa7f 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -20,6 +20,7 @@ #include "llvm/OperandTraits.h" #include "llvm/Operator.h" #include "llvm/DerivedTypes.h" +#include "llvm/ADT/Twine.h" namespace llvm { @@ -160,7 +161,7 @@ public: /// Instruction is allowed to be a dereferenced end iterator. /// static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2, - const Twine &Name = "", + const Twine &Name = Twine(), Instruction *InsertBefore = 0); /// Create() - Construct a binary instruction, given the opcode and the two @@ -277,6 +278,27 @@ public: return BO; } + /// CreateNSWMul - Create a Mul operator with the NSW flag set. + /// + static BinaryOperator *CreateNSWMul(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateMul(V1, V2, Name); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWMul(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateMul(V1, V2, Name, BB); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWMul(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateMul(V1, V2, Name, I); + BO->setHasNoSignedWrap(true); + return BO; + } + /// CreateExactSDiv - Create an SDiv operator with the exact flag set. /// static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, @@ -308,6 +330,10 @@ public: Instruction *InsertBefore = 0); static BinaryOperator *CreateNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); + static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "", + Instruction *InsertBefore = 0); + static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "", Instruction *InsertBefore = 0); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name, @@ -707,10 +733,12 @@ public: } /// @brief Return the predicate for this instruction. - Predicate getPredicate() const { return Predicate(SubclassData); } + Predicate getPredicate() const { + return Predicate(getSubclassDataFromInstruction()); + } /// @brief Set the predicate for this instruction to the specified value. - void setPredicate(Predicate P) { SubclassData = P; } + void setPredicate(Predicate P) { setInstructionSubclassData(P); } static bool isFPPredicate(Predicate P) { return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE; @@ -831,6 +859,12 @@ public: } return Type::getInt1Ty(opnd_type->getContext()); } +private: + // Shadow Value::setValueSubclassData with a private forwarding method so that + // subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } }; diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 07b3231..d45da97 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -21,6 +21,7 @@ namespace llvm { class LLVMContext; +class MDNode; template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; @@ -30,60 +31,21 @@ class Instruction : public User, public ilist_node<Instruction> { Instruction(const Instruction &); // Do not implement BasicBlock *Parent; - - friend class SymbolTableListTraits<Instruction, BasicBlock>; - void setParent(BasicBlock *P); -protected: - Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, - Instruction *InsertBefore = 0); - Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, - BasicBlock *InsertAtEnd); - virtual Instruction *clone_impl() const = 0; + + enum { + /// HasMetadataBit - This is a bit stored in the SubClassData field which + /// indicates whether this instruction has metadata attached to it or not. + HasMetadataBit = 1 << 15 + }; public: // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); - /// clone() - Create a copy of 'this' instruction that is identical in all - /// ways except the following: - /// * The instruction has no parent - /// * The instruction has no name - /// - Instruction *clone() const; - - /// isIdenticalTo - Return true if the specified instruction is exactly - /// identical to the current one. This means that all operands match and any - /// extra information (e.g. load is volatile) agree. - bool isIdenticalTo(const Instruction *I) const; - - /// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it - /// ignores the SubclassOptionalData flags, which specify conditions - /// under which the instruction's result is undefined. - bool isIdenticalToWhenDefined(const Instruction *I) const; - - /// This function determines if the specified instruction executes the same - /// operation as the current one. This means that the opcodes, type, operand - /// types and any other factors affecting the operation must be the same. This - /// is similar to isIdenticalTo except the operands themselves don't have to - /// be identical. - /// @returns true if the specified instruction is the same operation as - /// the current one. - /// @brief Determine if one instruction is the same operation as another. - bool isSameOperationAs(const Instruction *I) const; - - /// isUsedOutsideOfBlock - Return true if there are any uses of this - /// instruction in blocks other than the specified block. Note that PHI nodes - /// are considered to evaluate their operands in the corresponding predecessor - /// block. - bool isUsedOutsideOfBlock(const BasicBlock *BB) const; - - /// use_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. Instruction *use_back() { return cast<Instruction>(*use_begin());} const Instruction *use_back() const { return cast<Instruction>(*use_begin());} - // Accessor methods... - // inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } @@ -110,19 +72,19 @@ public: /// MovePos. void moveBefore(Instruction *MovePos); - // --------------------------------------------------------------------------- - /// Subclass classification... getOpcode() returns a member of - /// one of the enums that is coming soon (down below)... - /// + //===--------------------------------------------------------------------===// + // Subclass classification. + //===--------------------------------------------------------------------===// + + /// getOpcode() returns a member of one of the enums like Instruction::Add. unsigned getOpcode() const { return getValueID() - InstructionVal; } + const char *getOpcodeName() const { return getOpcodeName(getOpcode()); } bool isTerminator() const { return isTerminator(getOpcode()); } bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isShift() { return isShift(getOpcode()); } bool isCast() const { return isCast(getOpcode()); } - - static const char* getOpcodeName(unsigned OpCode); static inline bool isTerminator(unsigned OpCode) { @@ -154,6 +116,56 @@ public: return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; } + //===--------------------------------------------------------------------===// + // Metadata manipulation. + //===--------------------------------------------------------------------===// + + /// hasMetadata() - Return true if this instruction has any metadata attached + /// to it. + bool hasMetadata() const { + return (getSubclassDataFromValue() & HasMetadataBit) != 0; + } + + /// getMetadata - Get the metadata of given kind attached to this Instruction. + /// If the metadata is not found then return null. + MDNode *getMetadata(unsigned KindID) const { + if (!hasMetadata()) return 0; + return getMetadataImpl(KindID); + } + + /// getMetadata - Get the metadata of given kind attached to this Instruction. + /// If the metadata is not found then return null. + MDNode *getMetadata(const char *Kind) const { + if (!hasMetadata()) return 0; + return getMetadataImpl(Kind); + } + + /// getAllMetadata - Get all metadata attached to this Instruction. The first + /// element of each pair returned is the KindID, the second element is the + /// metadata value. This list is returned sorted by the KindID. + void getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const{ + if (hasMetadata()) + getAllMetadataImpl(MDs); + } + + /// setMetadata - Set the metadata of of the specified kind to the specified + /// node. This updates/replaces metadata if already present, or removes it if + /// Node is null. + void setMetadata(unsigned KindID, MDNode *Node); + void setMetadata(const char *Kind, MDNode *Node); + +private: + // These are all implemented in Metadata.cpp. + MDNode *getMetadataImpl(unsigned KindID) const; + MDNode *getMetadataImpl(const char *Kind) const; + void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode*> > &)const; + void removeAllMetadata(); +public: + //===--------------------------------------------------------------------===// + // Predicates and helper methods. + //===--------------------------------------------------------------------===// + + /// isAssociative - Return true if the instruction is associative: /// /// Associative operators satisfy: x op (y op z) === (x op y) op z @@ -216,6 +228,40 @@ public: /// for such instructions, moving them may change the resulting value. bool isSafeToSpeculativelyExecute() const; + /// clone() - Create a copy of 'this' instruction that is identical in all + /// ways except the following: + /// * The instruction has no parent + /// * The instruction has no name + /// + Instruction *clone() const; + + /// isIdenticalTo - Return true if the specified instruction is exactly + /// identical to the current one. This means that all operands match and any + /// extra information (e.g. load is volatile) agree. + bool isIdenticalTo(const Instruction *I) const; + + /// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it + /// ignores the SubclassOptionalData flags, which specify conditions + /// under which the instruction's result is undefined. + bool isIdenticalToWhenDefined(const Instruction *I) const; + + /// This function determines if the specified instruction executes the same + /// operation as the current one. This means that the opcodes, type, operand + /// types and any other factors affecting the operation must be the same. This + /// is similar to isIdenticalTo except the operands themselves don't have to + /// be identical. + /// @returns true if the specified instruction is the same operation as + /// the current one. + /// @brief Determine if one instruction is the same operation as another. + bool isSameOperationAs(const Instruction *I) const; + + /// isUsedOutsideOfBlock - Return true if there are any uses of this + /// instruction in blocks other than the specified block. Note that PHI nodes + /// are considered to evaluate their operands in the corresponding predecessor + /// block. + bool isUsedOutsideOfBlock(const BasicBlock *BB) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *) { return true; } static inline bool classof(const Value *V) { @@ -223,7 +269,7 @@ public: } //---------------------------------------------------------------------- - // Exported enumerations... + // Exported enumerations. // enum TermOps { // These terminate basic blocks #define FIRST_TERM_INST(N) TermOpsBegin = N, @@ -259,6 +305,43 @@ public: #define LAST_OTHER_INST(N) OtherOpsEnd = N+1 #include "llvm/Instruction.def" }; +private: + // Shadow Value::setValueSubclassData with a private forwarding method so that + // subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } + unsigned short getSubclassDataFromValue() const { + return Value::getSubclassDataFromValue(); + } + + void setHasMetadata(bool V) { + setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) | + (V ? HasMetadataBit : 0)); + } + + friend class SymbolTableListTraits<Instruction, BasicBlock>; + void setParent(BasicBlock *P); +protected: + // Instruction subclasses can stick up to 15 bits of stuff into the + // SubclassData field of instruction with these members. + + // Verify that only the low 15 bits are used. + void setInstructionSubclassData(unsigned short D) { + assert((D & HasMetadataBit) == 0 && "Out of range value put into field"); + setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D); + } + + unsigned getSubclassDataFromInstruction() const { + return getSubclassDataFromValue() & ~HasMetadataBit; + } + + Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, + Instruction *InsertBefore = 0); + Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, + BasicBlock *InsertAtEnd); + virtual Instruction *clone_impl() const = 0; + }; // Instruction* is only 4-byte aligned. diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 5b48e1a..c6cdbd5 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -82,7 +82,9 @@ public: /// getAlignment - Return the alignment of the memory that is being allocated /// by the instruction. /// - unsigned getAlignment() const { return (1u << SubclassData) >> 1; } + unsigned getAlignment() const { + return (1u << getSubclassDataFromInstruction()) >> 1; + } void setAlignment(unsigned Align); /// isStaticAlloca - Return true if this alloca is in the entry block of the @@ -98,6 +100,12 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } }; @@ -134,18 +142,19 @@ public: /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return SubclassData & 1; } + bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// setVolatile - Specify whether this is a volatile load or not. /// void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | (V ? 1 : 0); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + (V ? 1 : 0)); } /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { - return (1 << (SubclassData>>1)) >> 1; + return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1; } void setAlignment(unsigned Align); @@ -167,6 +176,12 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } }; @@ -200,12 +215,13 @@ public: /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return SubclassData & 1; } + bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// setVolatile - Specify whether this is a volatile load or not. /// void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | (V ? 1 : 0); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + (V ? 1 : 0)); } /// Transparently provide more efficient getOperand methods. @@ -214,7 +230,7 @@ public: /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { - return (1 << (SubclassData>>1)) >> 1; + return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1; } void setAlignment(unsigned Align); @@ -235,6 +251,12 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } }; template <> @@ -675,7 +697,7 @@ public: /// (e.g. ult). /// @brief Swap operands and adjust predicate. void swapOperands() { - SubclassData = getSwappedPredicate(); + setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } @@ -761,18 +783,18 @@ public: /// @returns true if the predicate of this instruction is EQ or NE. /// @brief Determine if this is an equality predicate. bool isEquality() const { - return SubclassData == FCMP_OEQ || SubclassData == FCMP_ONE || - SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE; + return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE || + getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE; } /// @returns true if the predicate of this instruction is commutative. /// @brief Determine if this is a commutative predicate. bool isCommutative() const { return isEquality() || - SubclassData == FCMP_FALSE || - SubclassData == FCMP_TRUE || - SubclassData == FCMP_ORD || - SubclassData == FCMP_UNO; + getPredicate() == FCMP_FALSE || + getPredicate() == FCMP_TRUE || + getPredicate() == FCMP_ORD || + getPredicate() == FCMP_UNO; } /// @returns true if the predicate is relational (not EQ or NE). @@ -785,7 +807,7 @@ public: /// (e.g. ult). /// @brief Swap operands and adjust predicate. void swapOperands() { - SubclassData = getSwappedPredicate(); + setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } @@ -800,14 +822,11 @@ public: }; //===----------------------------------------------------------------------===// -// CallInst Class -//===----------------------------------------------------------------------===// /// CallInst - This class represents a function call, abstracting a target /// machine's calling convention. This class uses low bit of the SubClassData /// field to indicate whether or not this is a tail call. The rest of the bits /// hold the calling convention of the call. /// - class CallInst : public Instruction { AttrListPtr AttributeList; ///< parameter attributes for call CallInst(const CallInst &CI); @@ -912,9 +931,10 @@ public: ~CallInst(); - bool isTailCall() const { return SubclassData & 1; } + bool isTailCall() const { return getSubclassDataFromInstruction() & 1; } void setTailCall(bool isTC = true) { - SubclassData = (SubclassData & ~1) | unsigned(isTC); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + unsigned(isTC)); } /// Provide fast operand accessors @@ -923,10 +943,11 @@ public: /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. CallingConv::ID getCallingConv() const { - return static_cast<CallingConv::ID>(SubclassData >> 1); + return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1); } void setCallingConv(CallingConv::ID CC) { - SubclassData = (SubclassData & 1) | (static_cast<unsigned>(CC) << 1); + setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + (static_cast<unsigned>(CC) << 1)); } /// getAttributes - Return the parameter attributes for this call. @@ -1024,6 +1045,12 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } }; template <> @@ -2401,10 +2428,10 @@ public: /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. CallingConv::ID getCallingConv() const { - return static_cast<CallingConv::ID>(SubclassData); + return static_cast<CallingConv::ID>(getSubclassDataFromInstruction()); } void setCallingConv(CallingConv::ID CC) { - SubclassData = static_cast<unsigned>(CC); + setInstructionSubclassData(static_cast<unsigned>(CC)); } /// getAttributes - Return the parameter attributes for this invoke. @@ -2528,6 +2555,12 @@ private: virtual BasicBlock *getSuccessorV(unsigned idx) const; virtual unsigned getNumSuccessorsV() const; virtual void setSuccessorV(unsigned idx, BasicBlock *B); + + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } }; template <> diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index a516409..3c18de1 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -25,7 +25,6 @@ #define LLVM_INTRINSICINST_H #include "llvm/Constants.h" -#include "llvm/Metadata.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" @@ -98,8 +97,8 @@ namespace llvm { return unsigned(cast<ConstantInt>(getOperand(2))->getZExtValue()); } - Value* getFileName() const; - Value* getDirectory() const; + Value *getFileName() const; + Value *getDirectory() const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const DbgStopPointInst *) { return true; } @@ -175,9 +174,7 @@ 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 *getValue() const; Value *getOffset() const { return getOperand(2); } MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); } diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 6ff87ba..c472f2b 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -260,7 +260,7 @@ def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; def int_siglongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>; // Internal interface for object size checking -def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i32_ty], +def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty], [IntrReadArgMem]>, GCCBuiltin<"__builtin_object_size">; diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index b9ffeb0..6d36d5e 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -18,7 +18,8 @@ namespace llvm { class LLVMContextImpl; -class MetadataContext; +class StringRef; +template <typename T> class SmallVectorImpl; /// This is an important class for using LLVM in a threaded context. It /// (opaquely) owns and manages the core "global" data of LLVM's core @@ -31,14 +32,23 @@ class LLVMContext { void operator=(LLVMContext&); public: - LLVMContextImpl* const pImpl; - MetadataContext &getMetadata(); + LLVMContextImpl *const pImpl; LLVMContext(); ~LLVMContext(); + + /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. + /// This ID is uniqued across modules in the current LLVMContext. + unsigned getMDKindID(StringRef Name) const; + + /// getMDKindNames - Populate client supplied SmallVector with the name for + /// custom metadata IDs registered in this LLVMContext. ID #0 is not used, + /// so it is filled in as an empty string. + void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; }; -/// FOR BACKWARDS COMPATIBILITY - Returns a global context. -extern LLVMContext& getGlobalContext(); +/// getGlobalContext - Returns a global context. This is for LLVM clients that +/// only care about operating on a single thread. +extern LLVMContext &getGlobalContext(); } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 8656927..be017bf 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -76,7 +76,7 @@ public: virtual uint64_t getMaxFileSize() const { assert(0 && "Invalid getMaxFileSize call!"); return 0; - }; + } /// @name Assembler Backend Support /// @{ diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index c7f2b44..ec6ba1b 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -17,18 +17,19 @@ #define LLVM_METADATA_H #include "llvm/Value.h" -#include "llvm/Type.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/ilist_node.h" -#include "llvm/Support/ValueHandle.h" namespace llvm { class Constant; class Instruction; class LLVMContext; -class MetadataContextImpl; - +class Module; +template <typename T> class SmallVectorImpl; +template<typename ValueSubClass, typename ItemParentClass> + class SymbolTableListTraits; + + //===----------------------------------------------------------------------===// // MetadataBase - A base class for MDNode, MDString and NamedMDNode. class MetadataBase : public Value { @@ -55,8 +56,7 @@ class MDString : public MetadataBase { StringRef Str; protected: - explicit MDString(LLVMContext &C, StringRef S) - : MetadataBase(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {} + explicit MDString(LLVMContext &C, StringRef S); public: static MDString *get(LLVMContext &Context, StringRef Str); @@ -83,53 +83,64 @@ public: } }; + +class MDNodeOperand; + //===----------------------------------------------------------------------===// /// MDNode - a tuple of other values. -/// These contain a list of the values that represent the metadata. -/// MDNode is always unnamed. class MDNode : public MetadataBase, public FoldingSetNode { MDNode(const MDNode &); // DO NOT IMPLEMENT + void operator=(const MDNode &); // DO NOT IMPLEMENT + friend class MDNodeOperand; - friend class ElementVH; - // Use CallbackVH to hold MDNode elements. - struct ElementVH : public CallbackVH { - MDNode *Parent; - ElementVH() {} - ElementVH(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {} - ~ElementVH() {} - - virtual void deleted() { - Parent->replaceElement(this->operator Value*(), 0); - } - - virtual void allUsesReplacedWith(Value *NV) { - Parent->replaceElement(this->operator Value*(), NV); - } + /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the + /// end of this MDNode. + unsigned NumOperands; + + // Subclass data enums. + enum { + /// FunctionLocalBit - This bit is set if this MDNode is function local. + /// This is true when it (potentially transitively) contains a reference to + /// something in a function, like an argument, basicblock, or instruction. + FunctionLocalBit = 1 << 0, + + /// NotUniquedBit - This is set on MDNodes that are not uniqued because they + /// have a null perand. + NotUniquedBit = 1 << 1, + + /// DestroyFlag - This bit is set by destroy() so the destructor can assert + /// that the node isn't being destroyed with a plain 'delete'. + DestroyFlag = 1 << 2 }; - // Replace each instance of F from the element list of this node with T. - void replaceElement(Value *F, Value *T); - - ElementVH *Node; - unsigned NodeSize; + + // Replace each instance of F from the operand list of this node with T. + void replaceOperand(MDNodeOperand *Op, Value *NewVal); + ~MDNode(); protected: - explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals); + explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, + bool isFunctionLocal); public: // Constructors and destructors. - static MDNode *get(LLVMContext &Context, - Value *const *Vals, unsigned NumVals); - - /// ~MDNode - Destroy MDNode. - ~MDNode(); + static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals, + bool isFunctionLocal = false); + + /// getOperand - Return specified operand. + Value *getOperand(unsigned i) const; - /// getElement - Return specified element. - Value *getElement(unsigned i) const { - assert(i < getNumElements() && "Invalid element number!"); - return Node[i]; + /// getNumOperands - Return number of MDNode operands. + unsigned getNumOperands() const { return NumOperands; } + + /// isFunctionLocal - Return whether MDNode is local to a function. + /// Note: MDNodes are designated as function-local when created, and keep + /// that designation even if their operands are modified to no longer + /// refer to function-local IR. + bool isFunctionLocal() const { + return (getSubclassDataFromValue() & FunctionLocalBit) != 0; } - /// getNumElements - Return number of MDNode elements. - unsigned getNumElements() const { return NodeSize; } + // destroy - Delete this node. Only when there are no uses. + void destroy(); /// Profile - calculate a unique identifier for this MDNode to collapse /// duplicates @@ -140,14 +151,24 @@ public: static bool classof(const Value *V) { return V->getValueID() == MDNodeVal; } +private: + bool isNotUniqued() const { + return (getSubclassDataFromValue() & NotUniquedBit) != 0; + } + void setIsNotUniqued() { + setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit); + } + + // Shadow Value::setValueSubclassData with a private forwarding method so that + // any future subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } }; //===----------------------------------------------------------------------===// /// NamedMDNode - a tuple of other metadata. -/// NamedMDNode is always named. All NamedMDNode element has a type of metadata. -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; - +/// NamedMDNode is always named. All NamedMDNode operand has a type of metadata. class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> { friend class SymbolTableListTraits<NamedMDNode, Module>; friend class LLVMContextImpl; @@ -155,7 +176,7 @@ class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> { NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT Module *Parent; - SmallVector<TrackingVH<MetadataBase>, 4> Node; + void *Operands; // SmallVector<TrackingVH<MetadataBase>, 4> void setParent(Module *M) { Parent = M; } protected: @@ -184,31 +205,15 @@ public: inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } - /// getElement - Return specified element. - MetadataBase *getElement(unsigned i) const { - assert(i < getNumElements() && "Invalid element number!"); - return Node[i]; - } - - /// getNumElements - Return number of NamedMDNode elements. - unsigned getNumElements() const { - return (unsigned)Node.size(); - } - - /// addElement - Add metadata element. - void addElement(MetadataBase *M) { - Node.push_back(TrackingVH<MetadataBase>(M)); - } - - typedef SmallVectorImpl<TrackingVH<MetadataBase> >::iterator elem_iterator; - typedef SmallVectorImpl<TrackingVH<MetadataBase> >::const_iterator - const_elem_iterator; - bool elem_empty() const { return Node.empty(); } - const_elem_iterator elem_begin() const { return Node.begin(); } - const_elem_iterator elem_end() const { return Node.end(); } - elem_iterator elem_begin() { return Node.begin(); } - elem_iterator elem_end() { return Node.end(); } + /// getOperand - Return specified operand. + MetadataBase *getOperand(unsigned i) const; + + /// getNumOperands - Return the number of NamedMDNode operands. + unsigned getNumOperands() const; + /// addOperand - Add metadata operand. + void addOperand(MetadataBase *M); + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const NamedMDNode *) { return true; } static bool classof(const Value *V) { @@ -216,69 +221,6 @@ public: } }; -//===----------------------------------------------------------------------===// -/// MetadataContext - -/// MetadataContext handles uniquing and assignment of IDs for custom metadata -/// types. Custom metadata handler names do not contain spaces. And the name -/// must start with an alphabet. The regular expression used to check name -/// is [a-zA-Z$._][a-zA-Z$._0-9]* -class MetadataContext { - // DO NOT IMPLEMENT - MetadataContext(MetadataContext&); - void operator=(MetadataContext&); - - MetadataContextImpl *const pImpl; -public: - MetadataContext(); - ~MetadataContext(); - - /// registerMDKind - Register a new metadata kind and return its ID. - /// A metadata kind can be registered only once. - unsigned registerMDKind(StringRef Name); - - /// getMDKind - Return metadata kind. If the requested metadata kind - /// is not registered then return 0. - unsigned getMDKind(StringRef Name) const; - - /// isValidName - Return true if Name is a valid custom metadata handler name. - static bool isValidName(StringRef Name); - - /// getMD - Get the metadata of given kind attached to an Instruction. - /// If the metadata is not found then return 0. - MDNode *getMD(unsigned Kind, const Instruction *Inst); - - /// getMDs - Get the metadata attached to an Instruction. - void getMDs(const Instruction *Inst, - SmallVectorImpl<std::pair<unsigned, TrackingVH<MDNode> > > &MDs) const; - - /// addMD - Attach the metadata of given kind to an Instruction. - void addMD(unsigned Kind, MDNode *Node, Instruction *Inst); - - /// removeMD - Remove metadata of given kind attached with an instuction. - void removeMD(unsigned Kind, Instruction *Inst); - - /// removeAllMetadata - Remove all metadata attached with an instruction. - void removeAllMetadata(Instruction *Inst); - - /// copyMD - If metadata is attached with Instruction In1 then attach - /// the same metadata to In2. - void copyMD(Instruction *In1, Instruction *In2); - - /// getHandlerNames - Populate client supplied smallvector using custom - /// metadata name and ID. - void getHandlerNames(SmallVectorImpl<std::pair<unsigned, StringRef> >&) const; - - /// ValueIsDeleted - This handler is used to update metadata store - /// when a value is deleted. - void ValueIsDeleted(const Value *) {} - void ValueIsDeleted(Instruction *Inst); - void ValueIsRAUWd(Value *V1, Value *V2); - - /// ValueIsCloned - This handler is used to update metadata store - /// when In1 is cloned to create In2. - void ValueIsCloned(const Instruction *In1, Instruction *In2); -}; - } // end llvm namespace #endif diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 04dfb35..9a8b53a 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -24,7 +24,6 @@ namespace llvm { -class GlobalValueRefMap; // Used by ConstantVals.cpp class FunctionType; class LLVMContext; @@ -132,7 +131,7 @@ public: /// @name Member Variables /// @{ private: - LLVMContext& Context; ///< The LLVMContext from which types and + LLVMContext &Context; ///< The LLVMContext from which types and ///< constants are allocated. GlobalListType GlobalList; ///< The Global Variables in the module FunctionListType FunctionList; ///< The Functions in the module @@ -161,7 +160,7 @@ public: /// @} /// @name Module Level Accessors /// @{ -public: + /// Get the module identifier which is, essentially, the name of the module. /// @returns the module identifier as a string const std::string &getModuleIdentifier() const { return ModuleID; } @@ -185,16 +184,16 @@ public: /// Get the global data context. /// @returns LLVMContext - a container for LLVM's global information - LLVMContext& getContext() const { return Context; } + LLVMContext &getContext() const { return Context; } /// Get any module-scope inline assembly blocks. /// @returns a string containing the module-scope inline assembly blocks. const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; } + /// @} /// @name Module Level Mutators /// @{ -public: - + /// Set the module identifier. void setModuleIdentifier(StringRef ID) { ModuleID = ID; } @@ -223,10 +222,19 @@ public: /// if a global with the specified name is not found. GlobalValue *getNamedValue(StringRef Name) const; + /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. + /// This ID is uniqued across modules in the current LLVMContext. + unsigned getMDKindID(StringRef Name) const; + + /// getMDKindNames - Populate client supplied SmallVector with the name for + /// custom metadata IDs registered in this LLVMContext. ID #0 is not used, + /// so it is filled in as an empty string. + void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; + /// @} /// @name Function Accessors /// @{ -public: + /// getOrInsertFunction - Look up the specified function in the module symbol /// table. Four possibilities: /// 1. If it does not exist, add a prototype for the function and return it. @@ -267,7 +275,7 @@ public: /// @} /// @name Global Variable Accessors /// @{ -public: + /// getGlobalVariable - Look up the specified global variable in the module /// symbol table. If it does not exist, return null. If AllowInternal is set /// to true, this function will return types that have InternalLinkage. By @@ -294,7 +302,7 @@ public: /// @} /// @name Global Alias Accessors /// @{ -public: + /// getNamedAlias - Return the first global alias in the module with the /// specified name, of arbitrary type. This method returns null if a global /// with the specified name is not found. @@ -303,7 +311,7 @@ public: /// @} /// @name Named Metadata Accessors /// @{ -public: + /// getNamedMetadata - Return the first NamedMDNode in the module with the /// specified name. This method returns null if a NamedMDNode with the /// specified name is not found. @@ -317,7 +325,7 @@ public: /// @} /// @name Type Accessors /// @{ -public: + /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If /// there is already an entry for this name, true is returned and the symbol /// table is not modified. @@ -334,7 +342,7 @@ public: /// @} /// @name Direct access to the globals list, functions list, and symbol table /// @{ -public: + /// Get the Module's list of global variables (constant). const GlobalListType &getGlobalList() const { return GlobalList; } /// Get the Module's list of global variables. @@ -375,7 +383,7 @@ public: /// @} /// @name Global Variable Iteration /// @{ -public: + /// Get an iterator to the first global variable global_iterator global_begin() { return GlobalList.begin(); } /// Get a constant iterator to the first global variable @@ -390,7 +398,7 @@ public: /// @} /// @name Function Iteration /// @{ -public: + /// Get an iterator to the first function. iterator begin() { return FunctionList.begin(); } /// Get a constant iterator to the first function. @@ -407,7 +415,7 @@ public: /// @} /// @name Dependent Library Iteration /// @{ -public: + /// @brief Get a constant iterator to beginning of dependent library list. inline lib_iterator lib_begin() const { return LibraryList.begin(); } /// @brief Get a constant iterator to end of dependent library list. @@ -424,7 +432,7 @@ public: /// @} /// @name Alias Iteration /// @{ -public: + /// Get an iterator to the first alias. alias_iterator alias_begin() { return AliasList.begin(); } /// Get a constant iterator to the first alias. @@ -442,31 +450,31 @@ public: /// @} /// @name Named Metadata Iteration /// @{ -public: + /// Get an iterator to the first named metadata. - named_metadata_iterator named_metadata_begin() - { return NamedMDList.begin(); } + named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); } /// Get a constant iterator to the first named metadata. - const_named_metadata_iterator named_metadata_begin() const - { return NamedMDList.begin(); } + const_named_metadata_iterator named_metadata_begin() const { + return NamedMDList.begin(); + } + /// Get an iterator to the last named metadata. - named_metadata_iterator named_metadata_end () - { return NamedMDList.end(); } + named_metadata_iterator named_metadata_end() { return NamedMDList.end(); } /// Get a constant iterator to the last named metadata. - const_named_metadata_iterator named_metadata_end () const - { return NamedMDList.end(); } + const_named_metadata_iterator named_metadata_end() const { + return NamedMDList.end(); + } + /// Determine how many NamedMDNodes are in the Module's list of named metadata. - size_t named_metadata_size () const - { return NamedMDList.size(); } + size_t named_metadata_size() const { return NamedMDList.size(); } /// Determine if the list of named metadata is empty. - bool named_metadata_empty() const - { return NamedMDList.empty(); } + bool named_metadata_empty() const { return NamedMDList.empty(); } /// @} /// @name Utility functions for printing and dumping Module objects /// @{ -public: + /// Print the module to an output stream with AssemblyAnnotationWriter. void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const; diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 35fb29e..37a7c3b 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -251,7 +251,7 @@ struct foo { }; template <> inline bool isa_impl<foo,bar>(const bar &Val) { - errs() << "Classof: " << &Val << "\n"; + dbgs() << "Classof: " << &Val << "\n"; return true; } diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 8861a20..1376e46 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -29,6 +29,12 @@ #define ATTRIBUTE_USED #endif +#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define ATTRIBUTE_UNUSED +#endif + #ifdef __GNUC__ // aka 'ATTRIBUTE_CONST' but following LLVM Conventions. #define ATTRIBUTE_READNONE __attribute__((__const__)) #else diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index b73cea0..1339e9f 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -54,6 +54,9 @@ public: Constant *CreateMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getMul(LHS, RHS); } + Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNSWMul(LHS, RHS); + } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFMul(LHS, RHS); } @@ -109,6 +112,9 @@ public: Constant *CreateNeg(Constant *C) const { return ConstantExpr::getNeg(C); } + Constant *CreateNSWNeg(Constant *C) const { + return ConstantExpr::getNSWNeg(C); + } Constant *CreateFNeg(Constant *C) const { return ConstantExpr::getFNeg(C); } diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index e8bc0ce..8651fc1 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -28,6 +28,8 @@ namespace llvm { +class raw_ostream; + /// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes /// all of their DEBUG statements to be activatable with -debug-only=thatstring. #ifndef DEBUG_TYPE @@ -58,7 +60,7 @@ void SetCurrentDebugType(const char *Type); /// this is a debug build, then the code specified as the option to the macro /// will be executed. Otherwise it will not be. Example: /// -/// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n"); +/// DEBUG_WITH_TYPE("bitset", dbgs() << "Bitset contains: " << Bitset << "\n"); /// /// This will emit the debug information if -debug is present, and -debug-only /// is not specified, or is specified as "bitset". @@ -72,15 +74,28 @@ void SetCurrentDebugType(const char *Type); #define DEBUG_WITH_TYPE(TYPE, X) do { } while (0) #endif +/// EnableDebugBuffering - This defaults to false. If true, the debug +/// stream will install signal handlers to dump any buffered debug +/// output. It allows clients to selectively allow the debug stream +/// to install signal handlers if they are certain there will be no +/// conflict. +/// +extern bool EnableDebugBuffering; + +/// dbgs() - This returns a reference to a raw_ostream for debugging +/// messages. If debugging is disabled it returns errs(). Use it +/// like: dbgs() << "foo" << "bar"; +raw_ostream &dbgs(); + // DEBUG macro - This macro should be used by passes to emit debug information. // In the '-debug' option is specified on the commandline, and if this is a // debug build, then the code specified as the option to the macro will be // executed. Otherwise it will not be. Example: // -// DEBUG(errs() << "Bitset contains: " << Bitset << "\n"); +// DEBUG(dbgs() << "Bitset contains: " << Bitset << "\n"); // #define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X) - + } // End llvm namespace #endif diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index 340f517..f64e3db 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -25,7 +25,12 @@ #include <cassert> #include <cstdio> -#ifdef WIN32 +#ifdef _MSC_VER +// FIXME: This define is wrong: +// - _snprintf does not guarantee that trailing null is always added - if +// there is no space for null, it does not report any error. +// - According to C++ standard, snprintf should be visible in the 'std' +// namespace - this define makes this impossible. #define snprintf _snprintf #endif diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index 24a3546..09ab17c 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -59,7 +59,7 @@ namespace llvm /// current_pos - Return the current position within the stream, /// not counting the bytes currently in the buffer. - virtual uint64_t current_pos() { + virtual uint64_t current_pos() const { // This has the same effect as calling TheStream.current_pos(), // but that interface is private. return TheStream->tell() - TheStream->GetNumBytesInBuffer(); diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 1310d70..eabf6ad 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -15,17 +15,13 @@ #ifndef LLVM_SUPPORT_IRBUILDER_H #define LLVM_SUPPORT_IRBUILDER_H -#include "llvm/Constants.h" #include "llvm/Instructions.h" -#include "llvm/GlobalAlias.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Function.h" -#include "llvm/Metadata.h" -#include "llvm/LLVMContext.h" +#include "llvm/BasicBlock.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ConstantFolder.h" namespace llvm { + class MDNode; /// IRBuilderDefaultInserter - This provides the default implementation of the /// IRBuilder 'InsertHelper' method that is called whenever an instruction is @@ -41,138 +37,72 @@ protected: I->setName(Name); } }; - - -/// IRBuilder - This provides a uniform API for creating instructions and -/// inserting them into a basic block: either at the end of a BasicBlock, or -/// at a specific iterator location in a block. -/// -/// Note that the builder does not expose the full generality of LLVM -/// instructions. For access to extra instruction properties, use the mutators -/// (e.g. setVolatile) on the instructions after they have been created. -/// The first template argument handles whether or not to preserve names in the -/// final instruction output. This defaults to on. The second template argument -/// specifies a class to use for creating constants. This defaults to creating -/// minimally folded constants. The fourth template argument allows clients to -/// specify custom insertion hooks that are called on every newly created -/// insertion. -template<bool preserveNames = true, typename T = ConstantFolder, - typename Inserter = IRBuilderDefaultInserter<preserveNames> > -class IRBuilder : public Inserter { + +/// IRBuilderBase - Common base class shared among various IRBuilders. +class IRBuilderBase { + unsigned DbgMDKind; + MDNode *CurDbgLocation; +protected: BasicBlock *BB; BasicBlock::iterator InsertPt; - unsigned MDKind; - MDNode *CurDbgLocation; LLVMContext &Context; - T Folder; public: - IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) - : Inserter(I), MDKind(0), CurDbgLocation(0), Context(C), Folder(F) { - ClearInsertionPoint(); - } - explicit IRBuilder(LLVMContext &C) - : MDKind(0), CurDbgLocation(0), Context(C), Folder(C) { + IRBuilderBase(LLVMContext &context) + : DbgMDKind(0), CurDbgLocation(0), Context(context) { ClearInsertionPoint(); } - explicit IRBuilder(BasicBlock *TheBB, const T &F) - : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) { - SetInsertPoint(TheBB); - } - - explicit IRBuilder(BasicBlock *TheBB) - : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), - Folder(Context) { - SetInsertPoint(TheBB); - } - - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) - : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) { - SetInsertPoint(TheBB, IP); - } - - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), - Folder(Context) { - SetInsertPoint(TheBB, IP); - } - - /// getFolder - Get the constant folder being used. - const T &getFolder() { return Folder; } - - /// isNamePreserving - Return true if this builder is configured to actually - /// add the requested names to IR created through it. - bool isNamePreserving() const { return preserveNames; } - //===--------------------------------------------------------------------===// // Builder configuration methods //===--------------------------------------------------------------------===// - + /// ClearInsertionPoint - Clear the insertion point: created instructions will /// not be inserted into a block. void ClearInsertionPoint() { BB = 0; } - + BasicBlock *GetInsertBlock() const { return BB; } - BasicBlock::iterator GetInsertPoint() const { return InsertPt; } - + /// SetInsertPoint - This specifies that created instructions should be /// appended to the end of the specified block. void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } - + /// SetInsertPoint - This specifies that created instructions should be /// inserted at the specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; } - + /// SetCurrentDebugLocation - Set location information used by debugging /// information. - void SetCurrentDebugLocation(MDNode *L) { - if (MDKind == 0) - MDKind = Context.getMetadata().getMDKind("dbg"); - if (MDKind == 0) - MDKind = Context.getMetadata().registerMDKind("dbg"); - CurDbgLocation = L; - } - + void SetCurrentDebugLocation(MDNode *L); MDNode *getCurrentDebugLocation() const { return CurDbgLocation; } - - /// SetDebugLocation - Set location information for the given instruction. - void SetDebugLocation(Instruction *I) { - if (CurDbgLocation) - Context.getMetadata().addMD(MDKind, CurDbgLocation, I); - } - - /// SetDebugLocation - Set location information for the given instruction. - void SetDebugLocation(Instruction *I, MDNode *Loc) { - if (MDKind == 0) - MDKind = Context.getMetadata().getMDKind("dbg"); - if (MDKind == 0) - MDKind = Context.getMetadata().registerMDKind("dbg"); - Context.getMetadata().addMD(MDKind, Loc, I); - } - - /// Insert - Insert and return the specified instruction. - template<typename InstTy> - InstTy *Insert(InstTy *I, const Twine &Name = "") const { - this->InsertHelper(I, Name, BB, InsertPt); - if (CurDbgLocation) - Context.getMetadata().addMD(MDKind, CurDbgLocation, I); - return I; - } + + /// SetInstDebugLocation - If this builder has a current debug location, set + /// it on the specified instruction. + void SetInstDebugLocation(Instruction *I) const; //===--------------------------------------------------------------------===// + // Miscellaneous creation methods. + //===--------------------------------------------------------------------===// + + /// CreateGlobalString - Make a new global variable with an initializer that + /// has array of i8 type filled in the the nul terminated string value + /// specified. If Name is specified, it is the name of the global variable + /// created. + Value *CreateGlobalString(const char *Str = "", const Twine &Name = ""); + + //===--------------------------------------------------------------------===// // Type creation methods //===--------------------------------------------------------------------===// - + /// getInt1Ty - Fetch the type representing a single bit const Type *getInt1Ty() { return Type::getInt1Ty(Context); @@ -197,7 +127,7 @@ public: const Type *getInt64Ty() { return Type::getInt64Ty(Context); } - + /// getFloatTy - Fetch the type representing a 32-bit floating point value. const Type *getFloatTy() { return Type::getFloatTy(Context); @@ -212,6 +142,72 @@ public: const Type *getVoidTy() { return Type::getVoidTy(Context); } + + /// getCurrentFunctionReturnType - Get the return type of the current function + /// that we're emitting into. + const Type *getCurrentFunctionReturnType() const; +}; + +/// IRBuilder - This provides a uniform API for creating instructions and +/// inserting them into a basic block: either at the end of a BasicBlock, or +/// at a specific iterator location in a block. +/// +/// Note that the builder does not expose the full generality of LLVM +/// instructions. For access to extra instruction properties, use the mutators +/// (e.g. setVolatile) on the instructions after they have been created. +/// The first template argument handles whether or not to preserve names in the +/// final instruction output. This defaults to on. The second template argument +/// specifies a class to use for creating constants. This defaults to creating +/// minimally folded constants. The fourth template argument allows clients to +/// specify custom insertion hooks that are called on every newly created +/// insertion. +template<bool preserveNames = true, typename T = ConstantFolder, + typename Inserter = IRBuilderDefaultInserter<preserveNames> > +class IRBuilder : public IRBuilderBase, public Inserter { + T Folder; +public: + IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) + : IRBuilderBase(C), Inserter(I), Folder(F) { + } + + explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder(C) { + } + + explicit IRBuilder(BasicBlock *TheBB, const T &F) + : IRBuilderBase(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB); + } + + explicit IRBuilder(BasicBlock *TheBB) + : IRBuilderBase(TheBB->getContext()), Folder(Context) { + SetInsertPoint(TheBB); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) + : IRBuilderBase(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB, IP); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) + : IRBuilderBase(TheBB->getContext()), Folder(Context) { + SetInsertPoint(TheBB, IP); + } + + /// getFolder - Get the constant folder being used. + const T &getFolder() { return Folder; } + + /// isNamePreserving - Return true if this builder is configured to actually + /// add the requested names to IR created through it. + bool isNamePreserving() const { return preserveNames; } + + /// Insert - Insert and return the specified instruction. + template<typename InstTy> + InstTy *Insert(InstTy *I, const Twine &Name = "") const { + this->InsertHelper(I, Name, BB, InsertPt); + if (getCurrentDebugLocation() != 0) + this->SetInstDebugLocation(I); + return I; + } //===--------------------------------------------------------------------===// // Instruction creation methods: Terminators @@ -228,7 +224,7 @@ public: ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(Context, V)); } - + /// CreateAggregateRet - Create a sequence of N insertvalue instructions, /// with one Value from the retVals array each, that build a aggregate /// return value one value at a time, and a ret instruction to return @@ -236,9 +232,8 @@ public: /// code that uses aggregate return values as a vehicle for having /// multiple return values. /// - ReturnInst *CreateAggregateRet(Value * const* retVals, unsigned N) { - const Type *RetType = BB->getParent()->getReturnType(); - Value *V = UndefValue::get(RetType); + ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { + Value *V = UndefValue::get(getCurrentFunctionReturnType()); for (unsigned i = 0; i != N; ++i) V = CreateInsertValue(V, retVals[i], i, "mrv"); return Insert(ReturnInst::Create(Context, V)); @@ -353,6 +348,12 @@ public: return Folder.CreateMul(LC, RC); return Insert(BinaryOperator::CreateMul(LHS, RHS), Name); } + Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNSWMul(LC, RC); + return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name); + } Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) @@ -478,6 +479,11 @@ public: return Folder.CreateNeg(VC); return Insert(BinaryOperator::CreateNeg(V), Name); } + Value *CreateNSWNeg(Value *V, const Twine &Name = "") { + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateNSWNeg(VC); + return Insert(BinaryOperator::CreateNSWNeg(V), Name); + } Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) return Folder.CreateFNeg(VC); @@ -639,26 +645,16 @@ public: Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); } - Value *CreateGlobalString(const char *Str = "", const Twine &Name = "") { - Constant *StrConstant = ConstantArray::get(Context, Str, true); - Module &M = *BB->getParent()->getParent(); - GlobalVariable *gv = new GlobalVariable(M, - StrConstant->getType(), - true, - GlobalValue::InternalLinkage, - StrConstant, - "", - 0, - false); - gv->setName(Name); - return gv; - } + + /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer + /// with "i8*" type instead of a pointer to array of i8. Value *CreateGlobalStringPtr(const char *Str = "", const Twine &Name = "") { Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; return CreateInBoundsGEP(gv, Args, Args+2, Name); } + //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 7f2f149..78a9035 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -60,6 +60,9 @@ public: Value *CreateMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateMul(LHS, RHS); } + Value *CreateNSWMul(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNSWMul(LHS, RHS); + } Value *CreateFMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFMul(LHS, RHS); } @@ -115,6 +118,9 @@ public: Value *CreateNeg(Constant *C) const { return BinaryOperator::CreateNeg(C); } + Value *CreateNSWNeg(Constant *C) const { + return BinaryOperator::CreateNSWNeg(C); + } Value *CreateNot(Constant *C) const { return BinaryOperator::CreateNot(C); } diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h index 18be1ad..f233c18 100644 --- a/include/llvm/Support/StandardPasses.h +++ b/include/llvm/Support/StandardPasses.h @@ -137,7 +137,8 @@ namespace llvm { if (UnrollLoops) PM->add(createLoopUnrollPass()); // Unroll small loops PM->add(createInstructionCombiningPass()); // Clean up after the unroller - PM->add(createGVNPass()); // Remove redundancies + if (OptimizationLevel > 1) + PM->add(createGVNPass()); // Remove redundancies PM->add(createMemCpyOptPass()); // Remove memcpy / form memset PM->add(createSCCPPass()); // Constant prop with SCCP diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index afed853..59dd29b 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -67,6 +67,9 @@ public: Constant *CreateMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getMul(LHS, RHS)); } + Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNSWMul(LHS, RHS)); + } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFMul(LHS, RHS)); } @@ -122,6 +125,9 @@ public: Constant *CreateNeg(Constant *C) const { return Fold(ConstantExpr::getNeg(C)); } + Constant *CreateNSWNeg(Constant *C) const { + return Fold(ConstantExpr::getNSWNeg(C)); + } Constant *CreateFNeg(Constant *C) const { return Fold(ConstantExpr::getFNeg(C)); } diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h new file mode 100644 index 0000000..2b3c329 --- /dev/null +++ b/include/llvm/Support/circular_raw_ostream.h @@ -0,0 +1,171 @@ +//===-- llvm/Support/circular_raw_ostream.h - Buffered streams --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains raw_ostream implementations for streams to do circular +// buffering of their output. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H +#define LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H + +#include "llvm/Support/raw_ostream.h" + +namespace llvm +{ + /// circular_raw_ostream - A raw_ostream which *can* save its data + /// to a circular buffer, or can pass it through directly to an + /// underlying stream if specified with a buffer of zero. + /// + class circular_raw_ostream : public raw_ostream { + public: + /// TAKE_OWNERSHIP - Tell this stream that it owns the underlying + /// stream and is responsible for cleanup, memory management + /// issues, etc. + /// + static const bool TAKE_OWNERSHIP = true; + + /// REFERENCE_ONLY - Tell this stream it should not manage the + /// held stream. + /// + static const bool REFERENCE_ONLY = false; + + private: + /// TheStream - The real stream we output to. We set it to be + /// unbuffered, since we're already doing our own buffering. + /// + raw_ostream *TheStream; + + /// OwnsStream - Are we responsible for managing the underlying + /// stream? + /// + bool OwnsStream; + + /// BufferSize - The size of the buffer in bytes. + /// + size_t BufferSize; + + /// BufferArray - The actual buffer storage. + /// + char *BufferArray; + + /// Cur - Pointer to the current output point in BufferArray. + /// + char *Cur; + + /// Filled - Indicate whether the buffer has been completely + /// filled. This helps avoid garbage output. + /// + bool Filled; + + /// Banner - A pointer to a banner to print before dumping the + /// log. + /// + const char *Banner; + + /// flushBuffer - Dump the contents of the buffer to Stream. + /// + void flushBuffer(void) { + if (Filled) + // Write the older portion of the buffer. + TheStream->write(Cur, BufferArray + BufferSize - Cur); + // Write the newer portion of the buffer. + TheStream->write(BufferArray, Cur - BufferArray); + Cur = BufferArray; + Filled = false; + } + + virtual void write_impl(const char *Ptr, size_t Size); + + /// current_pos - Return the current position within the stream, + /// not counting the bytes currently in the buffer. + /// + virtual uint64_t current_pos() const { + // This has the same effect as calling TheStream.current_pos(), + // but that interface is private. + return TheStream->tell() - TheStream->GetNumBytesInBuffer(); + } + + public: + /// circular_raw_ostream - Construct an optionally + /// circular-buffered stream, handing it an underlying stream to + /// do the "real" output. + /// + /// As a side effect, if BuffSize is nonzero, the given Stream is + /// set to be Unbuffered. This is because circular_raw_ostream + /// does its own buffering, so it doesn't want another layer of + /// buffering to be happening underneath it. + /// + /// "Owns" tells the circular_raw_ostream whether it is + /// responsible for managing the held stream, doing memory + /// management of it, etc. + /// + circular_raw_ostream(raw_ostream &Stream, const char *Header, + size_t BuffSize = 0, bool Owns = REFERENCE_ONLY) + : raw_ostream(/*unbuffered*/true), + TheStream(0), + OwnsStream(Owns), + BufferSize(BuffSize), + BufferArray(0), + Filled(false), + Banner(Header) { + if (BufferSize != 0) + BufferArray = new char[BufferSize]; + Cur = BufferArray; + setStream(Stream, Owns); + } + explicit circular_raw_ostream() + : raw_ostream(/*unbuffered*/true), + TheStream(0), + OwnsStream(REFERENCE_ONLY), + BufferArray(0), + Filled(false), + Banner("") { + Cur = BufferArray; + } + + ~circular_raw_ostream() { + flush(); + flushBufferWithBanner(); + releaseStream(); + delete[] BufferArray; + } + + /// setStream - Tell the circular_raw_ostream to output a + /// different stream. "Owns" tells circular_raw_ostream whether + /// it should take responsibility for managing the underlying + /// stream. + /// + void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) { + releaseStream(); + TheStream = &Stream; + OwnsStream = Owns; + } + + /// flushBufferWithBanner - Force output of the buffer along with + /// a small header. + /// + void flushBufferWithBanner(void); + + private: + /// releaseStream - Delete the held stream if needed. Otherwise, + /// transfer the buffer settings from this circular_raw_ostream + /// back to the underlying stream. + /// + void releaseStream() { + if (!TheStream) + return; + if (OwnsStream) + delete TheStream; + } + }; +} // end llvm namespace + + +#endif diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h index e0978b2..4f5d361 100644 --- a/include/llvm/Support/raw_os_ostream.h +++ b/include/llvm/Support/raw_os_ostream.h @@ -30,7 +30,7 @@ class raw_os_ostream : public raw_ostream { /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos(); + virtual uint64_t current_pos() const; public: raw_os_ostream(std::ostream &O) : OS(O) {} diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 2b3341d..d3c45c2 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -85,7 +85,7 @@ public: virtual ~raw_ostream(); /// tell - Return the current offset with the file. - uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); } + uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); } /// has_error - Return the value of the flag in this raw_ostream indicating /// whether an output error has been encountered. @@ -116,7 +116,7 @@ public: SetBufferAndMode(new char[Size], Size, InternalBuffer); } - size_t GetBufferSize() { + size_t GetBufferSize() const { // If we're supposed to be buffered but haven't actually gotten around // to allocating the buffer yet, return the value that would be used. if (BufferMode != Unbuffered && OutBufStart == 0) @@ -269,7 +269,7 @@ private: /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() = 0; + virtual uint64_t current_pos() const = 0; protected: /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is @@ -282,7 +282,7 @@ protected: /// preferred_buffer_size - Return an efficient buffer size for the /// underlying output mechanism. - virtual size_t preferred_buffer_size(); + virtual size_t preferred_buffer_size() const; /// error_detected - Set the flag indicating that an output error has /// been encountered. @@ -325,10 +325,10 @@ class raw_fd_ostream : public raw_ostream { /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() { return pos; } + virtual uint64_t current_pos() const { return pos; } /// preferred_buffer_size - Determine an efficient buffer size. - virtual size_t preferred_buffer_size(); + virtual size_t preferred_buffer_size() const; public: @@ -423,7 +423,7 @@ class raw_string_ostream : public raw_ostream { /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() { return OS.size(); } + virtual uint64_t current_pos() const { return OS.size(); } public: explicit raw_string_ostream(std::string &O) : OS(O) {} ~raw_string_ostream(); @@ -447,7 +447,7 @@ class raw_svector_ostream : public raw_ostream { /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos(); + virtual uint64_t current_pos() const; public: /// Construct a new raw_svector_ostream. /// @@ -468,7 +468,7 @@ class raw_null_ostream : public raw_ostream { /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos(); + virtual uint64_t current_pos() const; public: explicit raw_null_ostream() {} diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h index b8554c8..bdfb9aa 100644 --- a/include/llvm/System/Path.h +++ b/include/llvm/System/Path.h @@ -14,6 +14,7 @@ #ifndef LLVM_SYSTEM_PATH_H #define LLVM_SYSTEM_PATH_H +#include "llvm/ADT/StringRef.h" #include "llvm/System/TimeValue.h" #include <set> #include <string> @@ -159,7 +160,7 @@ namespace sys { /// between processes. /// @returns The dynamic link library suffix for the current platform. /// @brief Return the dynamic link library suffix. - static std::string GetDLLSuffix(); + static StringRef GetDLLSuffix(); /// GetMainExecutable - Return the path to the main executable, given the /// value of argv[0] from program startup and the address of main itself. @@ -174,12 +175,12 @@ namespace sys { Path() : path() {} Path(const Path &that) : path(that.path) {} - /// This constructor will accept a std::string as a path. No checking is - /// done on this path to determine if it is valid. To determine validity - /// of the path, use the isValid method. + /// This constructor will accept a char* or std::string as a path. No + /// checking is done on this path to determine if it is valid. To + /// determine validity of the path, use the isValid method. /// @param p The path to assign. /// @brief Construct a Path from a string. - explicit Path(const std::string& p); + explicit Path(StringRef p); /// This constructor will accept a character range as a path. No checking /// is done on this path to determine if it is valid. To determine @@ -202,10 +203,10 @@ namespace sys { } /// Makes a copy of \p that to \p this. - /// @param \p that A std::string denoting the path + /// @param \p that A StringRef denoting the path /// @returns \p this /// @brief Assignment Operator - Path &operator=(const std::string &that); + Path &operator=(StringRef that); /// Compares \p this Path with \p that Path for equality. /// @returns true if \p this and \p that refer to the same thing. @@ -251,28 +252,28 @@ namespace sys { /// component is the file or directory name occuring after the last /// directory separator. If no directory separator is present, the entire /// path name is returned (i.e. same as toString). - /// @returns std::string containing the last component of the path name. + /// @returns StringRef containing the last component of the path name. /// @brief Returns the last component of the path name. - std::string getLast() const; + StringRef getLast() const; /// This function strips off the path and suffix of the file or directory /// name and returns just the basename. For example /a/foo.bar would cause /// this function to return "foo". - /// @returns std::string containing the basename of the path + /// @returns StringRef containing the basename of the path /// @brief Get the base name of the path - std::string getBasename() const; + StringRef getBasename() const; /// This function strips off the suffix of the path beginning with the /// path separator ('/' on Unix, '\' on Windows) and returns the result. - std::string getDirname() const; + StringRef getDirname() const; /// This function strips off the path and basename(up to and /// including the last dot) of the file or directory name and /// returns just the suffix. For example /a/foo.bar would cause /// this function to return "bar". - /// @returns std::string containing the suffix of the path + /// @returns StringRef containing the suffix of the path /// @brief Get the suffix of the path - std::string getSuffix() const; + StringRef getSuffix() const; /// Obtain a 'C' string for the path name. /// @returns a 'C' string containing the path name. @@ -315,7 +316,7 @@ namespace sys { /// cases (file not found, file not accessible, etc.) it returns false. /// @returns true if the magic number of the file matches \p magic. /// @brief Determine if file has a specific magic number - bool hasMagicNumber(const std::string& magic) const; + bool hasMagicNumber(StringRef magic) const; /// This function retrieves the first \p len bytes of the file associated /// with \p this. These bytes are returned as the "magic number" in the @@ -422,8 +423,8 @@ namespace sys { /// Path object takes on the path value of \p unverified_path /// @returns true if the path was set, false otherwise. /// @param unverified_path The path to be set in Path object. - /// @brief Set a full path from a std::string - bool set(const std::string& unverified_path); + /// @brief Set a full path from a StringRef + bool set(StringRef unverified_path); /// One path component is removed from the Path. If only one component is /// present in the path, the Path object becomes empty. If the Path object @@ -437,7 +438,7 @@ namespace sys { /// needed. /// @returns false if the path component could not be added. /// @brief Appends one path component to the Path. - bool appendComponent( const std::string& component ); + bool appendComponent(StringRef component); /// A period and the \p suffix are appended to the end of the pathname. /// The precondition for this function is that the Path reference a file @@ -446,7 +447,7 @@ namespace sys { /// become invalid for the host operating system, false is returned. /// @returns false if the suffix could not be added, true if it was. /// @brief Adds a period and the \p suffix to the end of the pathname. - bool appendSuffix(const std::string& suffix); + bool appendSuffix(StringRef suffix); /// The suffix of the filename is erased. The suffix begins with and /// includes the last . character in the filename after the last directory @@ -620,12 +621,12 @@ namespace sys { PathWithStatus(const Path &other) : Path(other), status(), fsIsValid(false) {} - /// This constructor will accept a std::string as a path. No checking is - /// done on this path to determine if it is valid. To determine validity - /// of the path, use the isValid method. + /// This constructor will accept a char* or std::string as a path. No + /// checking is done on this path to determine if it is valid. To + /// determine validity of the path, use the isValid method. /// @brief Construct a Path from a string. explicit PathWithStatus( - const std::string& p ///< The path to assign. + StringRef p ///< The path to assign. ) : Path(p), status(), fsIsValid(false) {} /// This constructor will accept a character range as a path. No checking diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h index b0ed0bf..9efb683 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/Target/TargetInstrDesc.h @@ -25,9 +25,10 @@ class TargetRegisterInfo; //===----------------------------------------------------------------------===// namespace TOI { - // Operand constraints: only "tied_to" for now. + // Operand constraints enum OperandConstraint { - TIED_TO = 0 // Must be allocated the same register as. + TIED_TO = 0, // Must be allocated the same register as. + EARLY_CLOBBER // Operand is an early clobber register operand }; /// OperandFlags - These are flags set on operands, but should be considered diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 9536e04..dd28a87 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -139,6 +139,12 @@ public: virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; + /// getCmpLibcallReturnType - Return the ValueType for comparison + /// libcalls. Comparions libcalls include floating point comparion calls, + /// and Ordered/Unordered check calls on floating point numbers. + virtual + MVT::SimpleValueType getCmpLibcallReturnType() const; + /// getBooleanContents - For targets without i1 registers, this gives the /// nature of the high-bits of boolean values held in types wider than i1. /// "Boolean values" are special true/false values produced by nodes like @@ -1136,7 +1142,7 @@ public: bool isVarArg, bool isInreg, unsigned NumFixedArgs, CallingConv::ID CallConv, bool isTailCall, bool isReturnValueUsed, SDValue Callee, ArgListTy &Args, - SelectionDAG &DAG, DebugLoc dl); + SelectionDAG &DAG, DebugLoc dl, unsigned Order); /// LowerCall - This hook must be implemented to lower calls into the /// the specified DAG. The outgoing arguments to the call are described @@ -1291,20 +1297,6 @@ public: return false; } - /// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if - /// it exists. Skip a possible ISD::TokenFactor. - static SDValue GetPossiblePreceedingTailCall(SDValue Chain, - unsigned TailCallNodeOpCode) { - if (Chain.getOpcode() == TailCallNodeOpCode) { - return Chain; - } else if (Chain.getOpcode() == ISD::TokenFactor) { - if (Chain.getNumOperands() && - Chain.getOperand(0).getOpcode() == TailCallNodeOpCode) - return Chain.getOperand(0); - } - return Chain; - } - /// getTargetNodeName() - This method returns the name of a target specific /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 1104635..84cd5b4 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -292,6 +292,13 @@ protected: // Can only create subclasses. /// bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level); +private: + // These routines are used by addPassesToEmitFileFinish and + // addPassesToEmitMachineCode to set the CodeModel if it's still marked + // as default. + virtual void setCodeModelForJIT(); + virtual void setCodeModelForStatic(); + public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 8d52dad..b43450d 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -141,6 +141,11 @@ namespace llvm { /// wth earlier copy coalescing. extern bool StrongPHIElim; + /// DisableScheduling - This flag disables instruction scheduling. In + /// particular, it assigns an ordering to the SDNodes, which the scheduler + /// uses instead of its normal heuristics to perform scheduling. + extern bool DisableScheduling; + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index e9099f8..7fbbef9 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -38,7 +38,6 @@ class CallGraph; class TargetData; class Loop; class LoopInfo; -class LLVMContext; class AllocaInst; template <typename T> class SmallVectorImpl; diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index e6687bb..2cdd31f 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -27,7 +27,6 @@ class PHINode; class AllocaInst; class ConstantExpr; class TargetData; -class LLVMContext; struct DbgInfoIntrinsic; template<typename T> class SmallVectorImpl; diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 2364330..927e156 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -29,8 +29,8 @@ namespace llvm { class SSAUpdater { /// 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. We use - /// WeakVH's for the value of the map because we RAUW PHI nodes when we - /// eliminate them, and want the WeakVH to track this. + /// TrackingVH's for the value of the map because we RAUW PHI nodes when we + /// eliminate them, and want the TrackingVH's to track this. //typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy; void *AV; diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 752635c..e516982 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -7,14 +7,12 @@ // //===----------------------------------------------------------------------===// - #ifndef LLVM_TYPE_H #define LLVM_TYPE_H #include "llvm/AbstractTypeUser.h" #include "llvm/Support/Casting.h" #include "llvm/System/DataTypes.h" -#include "llvm/System/Atomic.h" #include "llvm/ADT/GraphTraits.h" #include <string> #include <vector> @@ -104,7 +102,7 @@ private: /// has no AbstractTypeUsers, the type is deleted. This is only sensical for /// derived types. /// - mutable sys::cas_flag RefCount; + mutable unsigned RefCount; /// Context - This refers to the LLVMContext in which this type was uniqued. LLVMContext &Context; @@ -401,7 +399,7 @@ public: void addRef() const { assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); - sys::AtomicIncrement(&RefCount); + ++RefCount; } void dropRef() const { @@ -410,8 +408,7 @@ public: // If this is the last PATypeHolder using this object, and there are no // PATypeHandles using it, the type is dead, delete it now. - sys::cas_flag OldCount = sys::AtomicDecrement(&RefCount); - if (OldCount == 0 && AbstractTypeUsers.empty()) + if (--RefCount == 0 && AbstractTypeUsers.empty()) this->destroy(); } diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 0960346..f0bd8be 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -17,7 +17,6 @@ #include "llvm/AbstractTypeUser.h" #include "llvm/Use.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/Casting.h" #include <string> @@ -42,7 +41,8 @@ class raw_ostream; class AssemblyAnnotationWriter; class ValueHandleBase; class LLVMContext; -class MetadataContextImpl; +class Twine; +class MDNode; //===----------------------------------------------------------------------===// // Value Class @@ -57,14 +57,13 @@ class MetadataContextImpl; /// /// Every value has a "use list" that keeps track of which other Values are /// using this Value. A Value can also have an arbitrary number of ValueHandle -/// objects that watch it and listen to RAUW and Destroy events see +/// objects that watch it and listen to RAUW and Destroy events. See /// llvm/Support/ValueHandle.h for details. /// /// @brief LLVM Value Representation class Value { const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? - unsigned char HasMetadata : 1; // Has a metadata attached to this ? protected: /// SubclassOptionalData - This member is similar to SubclassData, however it /// is for holding information which may be used to aid optimization, but @@ -72,18 +71,17 @@ protected: /// interpretation. unsigned char SubclassOptionalData : 7; +private: /// SubclassData - This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. unsigned short SubclassData; -private: + PATypeHolder VTy; Use *UseList; friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. - friend class SymbolTable; // Allow SymbolTable to directly poke Name. friend class ValueHandleBase; - friend class MetadataContextImpl; friend class AbstractTypeUser; ValueName *Name; @@ -303,9 +301,10 @@ public: const BasicBlock *PredBB) const{ return const_cast<Value*>(this)->DoPHITranslation(CurBB, PredBB); } - - /// hasMetadata - Return true if metadata is attached with this value. - bool hasMetadata() const { return HasMetadata; } + +protected: + unsigned short getSubclassDataFromValue() const { return SubclassData; } + void setValueSubclassData(unsigned short D) { SubclassData = D; } }; inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) { @@ -352,6 +351,9 @@ template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) { return isa<GlobalVariable>(Val) || isa<Function>(Val) || isa<GlobalAlias>(Val); } +template <> inline bool isa_impl<MDNode, Value>(const Value &Val) { + return Val.getValueID() == Value::MDNodeVal; +} // Value* is only 4-byte aligned. |