diff options
Diffstat (limited to 'include/llvm')
95 files changed, 2385 insertions, 1468 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 3f67ffb..ec76fbd 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -870,12 +870,28 @@ public: /// @brief Unsigned less than comparison bool ult(const APInt& RHS) const; + /// Regards both *this as an unsigned quantity and compares it with RHS for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when considered unsigned. + /// @brief Unsigned less than comparison + bool ult(uint64_t RHS) const { + return ult(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-than relationship. /// @returns true if *this < RHS when both are considered signed. /// @brief Signed less than comparison bool slt(const APInt& RHS) const; + /// Regards both *this as a signed quantity and compares it with RHS for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when considered signed. + /// @brief Signed less than comparison + bool slt(uint64_t RHS) const { + return slt(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the less-or-equal relationship. /// @returns true if *this <= RHS when both are considered unsigned. @@ -884,6 +900,14 @@ public: return ult(RHS) || eq(RHS); } + /// Regards both *this as an unsigned quantity and compares it with RHS for + /// the validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when considered unsigned. + /// @brief Unsigned less or equal comparison + bool ule(uint64_t RHS) const { + return ule(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-or-equal relationship. /// @returns true if *this <= RHS when both are considered signed. @@ -892,6 +916,14 @@ public: return slt(RHS) || eq(RHS); } + /// Regards both *this as a signed quantity and compares it with RHS for + /// the validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when considered signed. + /// @brief Signed less or equal comparison + bool sle(uint64_t RHS) const { + return sle(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as unsigned quantities and compares them for /// the validity of the greater-than relationship. /// @returns true if *this > RHS when both are considered unsigned. @@ -900,6 +932,14 @@ public: return !ult(RHS) && !eq(RHS); } + /// Regards both *this as an unsigned quantity and compares it with RHS for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when considered unsigned. + /// @brief Unsigned greater than comparison + bool ugt(uint64_t RHS) const { + return ugt(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as signed quantities and compares them for /// the validity of the greater-than relationship. /// @returns true if *this > RHS when both are considered signed. @@ -908,6 +948,14 @@ public: return !slt(RHS) && !eq(RHS); } + /// Regards both *this as a signed quantity and compares it with RHS for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when considered signed. + /// @brief Signed greater than comparison + bool sgt(uint64_t RHS) const { + return sgt(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the greater-or-equal relationship. /// @returns true if *this >= RHS when both are considered unsigned. @@ -916,6 +964,14 @@ public: return !ult(RHS); } + /// Regards both *this as an unsigned quantity and compares it with RHS for + /// the validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when considered unsigned. + /// @brief Unsigned greater or equal comparison + bool uge(uint64_t RHS) const { + return uge(APInt(getBitWidth(), RHS)); + } + /// Regards both *this and RHS as signed quantities and compares them for /// validity of the greater-or-equal relationship. /// @returns true if *this >= RHS when both are considered signed. @@ -924,6 +980,14 @@ public: return !slt(RHS); } + /// Regards both *this as a signed quantity and compares it with RHS for + /// the validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when considered signed. + /// @brief Signed greater or equal comparison + bool sge(uint64_t RHS) const { + return sge(APInt(getBitWidth(), RHS)); + } + /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. bool intersects(const APInt &RHS) const { diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 3a86b0d..9dcb9e1 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -49,6 +49,11 @@ public: ~reference() {} + reference &operator=(reference t) { + *this = bool(t); + return *this; + } + reference& operator=(bool t) { if (t) *WordRef |= 1L << BitPos; diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 41197a1..5299386 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -92,6 +92,16 @@ template<> struct DenseMapInfo<unsigned long long> { } }; +// Provide DenseMapInfo for ints. +template<> struct DenseMapInfo<int> { + static inline int getEmptyKey() { return 0x7fffffff; } + static inline int getTombstoneKey() { return -0x7fffffff - 1; } + static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); } + static bool isEqual(const int& LHS, const int& RHS) { + return LHS == RHS; + } +}; + // Provide DenseMapInfo for long longs. template<> struct DenseMapInfo<long long> { static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 65e70e2..70c3caf 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -189,6 +189,8 @@ public: unsigned verify() const { unsigned HL = getLeft() ? getLeft()->verify() : 0; unsigned HR = getRight() ? getRight()->verify() : 0; + (void) HL; + (void) HR; assert(getHeight() == ( HL > HR ? HL : HR ) + 1 && "Height calculation wrong"); diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h new file mode 100644 index 0000000..34e54a0 --- /dev/null +++ b/include/llvm/ADT/Optional.h @@ -0,0 +1,66 @@ +//===-- Optional.h - Simple variant for passing optional values ---*- 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 Optional, a template class modeled in the spirit of +// OCaml's 'opt' variant. The idea is to strongly type whether or not +// a value can be optional. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_OPTIONAL +#define LLVM_ADT_OPTIONAL + +#include <cassert> + +namespace llvm { + +template<typename T> +class Optional { + T x; + unsigned hasVal : 1; +public: + explicit Optional() : x(), hasVal(false) {} + Optional(const T &y) : x(y), hasVal(true) {} + + static inline Optional create(const T* y) { + return y ? Optional(*y) : Optional(); + } + + Optional &operator=(const T &y) { + x = y; + hasVal = true; + return *this; + } + + const T* getPointer() const { assert(hasVal); return &x; } + const T& getValue() const { assert(hasVal); return x; } + + operator bool() const { return hasVal; } + bool hasValue() const { return hasVal; } + const T* operator->() const { return getPointer(); } + const T& operator*() const { assert(hasVal); return x; } +}; + +template<typename T> struct simplify_type; + +template <typename T> +struct simplify_type<const Optional<T> > { + typedef const T* SimpleType; + static SimpleType getSimplifiedValue(const Optional<T> &Val) { + return Val.getPointer(); + } +}; + +template <typename T> +struct simplify_type<Optional<T> > + : public simplify_type<const Optional<T> > {}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index d38ce4c..c49d599 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -66,7 +66,7 @@ class scc_iterator std::vector<unsigned> MinVisitNumStack; // A single "visit" within the non-recursive DFS traversal. - void DFSVisitOne(NodeType* N) { + void DFSVisitOne(NodeType *N) { ++visitNum; // Global counter for the visit order nodeVisitNumbers[N] = visitNum; SCCNodeStack.push_back(N); @@ -83,13 +83,14 @@ class scc_iterator // TOS has at least one more child so continue DFS NodeType *childN = *VisitStack.back().second++; if (!nodeVisitNumbers.count(childN)) { - // this node has never been seen + // this node has never been seen. DFSVisitOne(childN); - } else { - unsigned childNum = nodeVisitNumbers[childN]; - if (MinVisitNumStack.back() > childNum) - MinVisitNumStack.back() = childNum; + continue; } + + unsigned childNum = nodeVisitNumbers[childN]; + if (MinVisitNumStack.back() > childNum) + MinVisitNumStack.back() = childNum; } } @@ -100,7 +101,7 @@ class scc_iterator while (!VisitStack.empty()) { DFSVisitChildren(); assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first)); - NodeType* visitingN = VisitStack.back().first; + NodeType *visitingN = VisitStack.back().first; unsigned minVisitNum = MinVisitNumStack.back(); VisitStack.pop_back(); MinVisitNumStack.pop_back(); @@ -111,18 +112,19 @@ class scc_iterator // " : minVisitNum = " << minVisitNum << "; Node visit num = " << // nodeVisitNumbers[visitingN] << "\n"; - if (minVisitNum == nodeVisitNumbers[visitingN]) { - // A full SCC is on the SCCNodeStack! It includes all nodes below - // visitingN on the stack. Copy those nodes to CurrentSCC, - // reset their minVisit values, and return (this suspends - // the DFS traversal till the next ++). - do { - CurrentSCC.push_back(SCCNodeStack.back()); - SCCNodeStack.pop_back(); - nodeVisitNumbers[CurrentSCC.back()] = ~0U; - } while (CurrentSCC.back() != visitingN); - return; - } + if (minVisitNum != nodeVisitNumbers[visitingN]) + continue; + + // A full SCC is on the SCCNodeStack! It includes all nodes below + // visitingN on the stack. Copy those nodes to CurrentSCC, + // reset their minVisit values, and return (this suspends + // the DFS traversal till the next ++). + do { + CurrentSCC.push_back(SCCNodeStack.back()); + SCCNodeStack.pop_back(); + nodeVisitNumbers[CurrentSCC.back()] = ~0U; + } while (CurrentSCC.back() != visitingN); + return; } } @@ -136,11 +138,11 @@ public: typedef scc_iterator<GraphT, GT> _Self; // Provide static "constructors"... - static inline _Self begin(const GraphT& G) { return _Self(GT::getEntryNode(G)); } - static inline _Self end (const GraphT& G) { return _Self(); } + static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));} + static inline _Self end (const GraphT &G) { return _Self(); } - // Direct loop termination test (I.fini() is more efficient than I == end()) - inline bool fini() const { + // Direct loop termination test: I.isAtEnd() is more efficient than I == end() + inline bool isAtEnd() const { assert(!CurrentSCC.empty() || VisitStack.empty()); return CurrentSCC.empty(); } @@ -181,28 +183,36 @@ public: return true; return false; } + + /// ReplaceNode - This informs the scc_iterator that the specified Old node + /// has been deleted, and New is to be used in its place. + void ReplaceNode(NodeType *Old, NodeType *New) { + assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?"); + nodeVisitNumbers[New] = nodeVisitNumbers[Old]; + nodeVisitNumbers.erase(Old); + } }; // Global constructor for the SCC iterator. template <class T> -scc_iterator<T> scc_begin(const T& G) { +scc_iterator<T> scc_begin(const T &G) { return scc_iterator<T>::begin(G); } template <class T> -scc_iterator<T> scc_end(const T& G) { +scc_iterator<T> scc_end(const T &G) { return scc_iterator<T>::end(G); } template <class T> -scc_iterator<Inverse<T> > scc_begin(const Inverse<T>& G) { - return scc_iterator<Inverse<T> >::begin(G); +scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) { + return scc_iterator<Inverse<T> >::begin(G); } template <class T> -scc_iterator<Inverse<T> > scc_end(const Inverse<T>& G) { - return scc_iterator<Inverse<T> >::end(G); +scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) { + return scc_iterator<Inverse<T> >::end(G); } } // End llvm namespace diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 5c774b9..3441d0a 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -15,7 +15,6 @@ #define LLVM_ADT_SMALLBITVECTOR_H #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/MathExtras.h" #include <cassert> @@ -32,48 +31,85 @@ class SmallBitVector { // TODO: In "large" mode, a pointer to a BitVector is used, leading to an // unnecessary level of indirection. It would be more efficient to use a // pointer to memory containing size, allocation size, and the array of bits. - PointerIntPair<BitVector *, 1, uintptr_t> X; + uintptr_t X; - // The number of bits in this class. - static const size_t NumBaseBits = sizeof(uintptr_t) * CHAR_BIT; + enum { + // The number of bits in this class. + NumBaseBits = sizeof(uintptr_t) * CHAR_BIT, - // One bit is used to discriminate between small and large mode. The - // remaining bits are used for the small-mode representation. - static const size_t SmallNumRawBits = NumBaseBits - 1; + // One bit is used to discriminate between small and large mode. The + // remaining bits are used for the small-mode representation. + SmallNumRawBits = NumBaseBits - 1, - // A few more bits are used to store the size of the bit set in small mode. - // Theoretically this is a ceil-log2. These bits are encoded in the most - // significant bits of the raw bits. - static const size_t SmallNumSizeBits = (NumBaseBits == 32 ? 5 : - NumBaseBits == 64 ? 6 : - SmallNumRawBits); + // A few more bits are used to store the size of the bit set in small mode. + // Theoretically this is a ceil-log2. These bits are encoded in the most + // significant bits of the raw bits. + SmallNumSizeBits = (NumBaseBits == 32 ? 5 : + NumBaseBits == 64 ? 6 : + SmallNumRawBits), - // The remaining bits are used to store the actual set in small mode. - static const size_t SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits; + // The remaining bits are used to store the actual set in small mode. + SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits + }; +public: + // Encapsulation of a single bit. + class reference { + SmallBitVector &TheVector; + unsigned BitPos; + + public: + reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} + + reference& operator=(reference t) { + *this = bool(t); + return *this; + } + + reference& operator=(bool t) { + if (t) + TheVector.set(BitPos); + else + TheVector.reset(BitPos); + return *this; + } + + operator bool() const { + return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos); + } + }; + +private: bool isSmall() const { - return X.getInt(); + return X & uintptr_t(1); + } + + BitVector *getPointer() const { + assert(!isSmall()); + return reinterpret_cast<BitVector *>(X); } void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) { - X.setInt(true); + X = 1; setSmallSize(NewSize); setSmallBits(NewSmallBits); } void switchToLarge(BitVector *BV) { - X.setInt(false); - X.setPointer(BV); + X = reinterpret_cast<uintptr_t>(BV); + assert(!isSmall() && "Tried to use an unaligned pointer"); } // Return all the bits used for the "small" representation; this includes // bits for the size as well as the element bits. uintptr_t getSmallRawBits() const { - return reinterpret_cast<uintptr_t>(X.getPointer()) >> 1; + assert(isSmall()); + return X >> 1; } void setSmallRawBits(uintptr_t NewRawBits) { - return X.setPointer(reinterpret_cast<BitVector *>(NewRawBits << 1)); + assert(isSmall()); + X = (NewRawBits << 1) | uintptr_t(1); } // Return the size. @@ -87,22 +123,22 @@ class SmallBitVector { // Return the element bits. uintptr_t getSmallBits() const { - return getSmallRawBits() & ~(~uintptr_t(0) << SmallNumDataBits); + return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize()); } void setSmallBits(uintptr_t NewBits) { - setSmallRawBits((getSmallRawBits() & (~uintptr_t(0) << SmallNumDataBits)) | - (NewBits & ~(~uintptr_t(0) << getSmallSize()))); + setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) | + (getSmallSize() << SmallNumDataBits)); } public: /// SmallBitVector default ctor - Creates an empty bitvector. - SmallBitVector() : X(0, 1) {} + SmallBitVector() : X(1) {} /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All /// bits are initialized to the specified value. - explicit SmallBitVector(unsigned s, bool t = false) : X(0, 1) { - if (s <= SmallNumRawBits) + explicit SmallBitVector(unsigned s, bool t = false) { + if (s <= SmallNumDataBits) switchToSmall(t ? ~uintptr_t(0) : 0, s); else switchToLarge(new BitVector(s, t)); @@ -113,22 +149,22 @@ public: if (RHS.isSmall()) X = RHS.X; else - switchToLarge(new BitVector(*RHS.X.getPointer())); + switchToLarge(new BitVector(*RHS.getPointer())); } ~SmallBitVector() { if (!isSmall()) - delete X.getPointer(); + delete getPointer(); } /// empty - Tests whether there are no bits in this bitvector. bool empty() const { - return isSmall() ? getSmallSize() == 0 : X.getPointer()->empty(); + return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); } /// size - Returns the number of bits in this bitvector. size_t size() const { - return isSmall() ? getSmallSize() : X.getPointer()->size(); + return isSmall() ? getSmallSize() : getPointer()->size(); } /// count - Returns the number of bits which are set. @@ -141,21 +177,21 @@ public: return CountPopulation_64(Bits); assert(0 && "Unsupported!"); } - return X.getPointer()->count(); + return getPointer()->count(); } /// any - Returns true if any bit is set. bool any() const { if (isSmall()) return getSmallBits() != 0; - return X.getPointer()->any(); + return getPointer()->any(); } /// none - Returns true if none of the bits are set. bool none() const { if (isSmall()) return getSmallBits() == 0; - return X.getPointer()->none(); + return getPointer()->none(); } /// find_first - Returns the index of the first set bit, -1 if none @@ -163,13 +199,15 @@ public: int find_first() const { if (isSmall()) { uintptr_t Bits = getSmallBits(); + if (Bits == 0) + return -1; if (sizeof(uintptr_t) * CHAR_BIT == 32) return CountTrailingZeros_32(Bits); if (sizeof(uintptr_t) * CHAR_BIT == 64) return CountTrailingZeros_64(Bits); assert(0 && "Unsupported!"); } - return X.getPointer()->find_first(); + return getPointer()->find_first(); } /// find_next - Returns the index of the next set bit following the @@ -178,30 +216,33 @@ public: if (isSmall()) { uintptr_t Bits = getSmallBits(); // Mask off previous bits. - Bits &= ~uintptr_t(0) << Prev; + Bits &= ~uintptr_t(0) << (Prev + 1); + if (Bits == 0 || Prev + 1 >= getSmallSize()) + return -1; if (sizeof(uintptr_t) * CHAR_BIT == 32) return CountTrailingZeros_32(Bits); if (sizeof(uintptr_t) * CHAR_BIT == 64) return CountTrailingZeros_64(Bits); assert(0 && "Unsupported!"); } - return X.getPointer()->find_next(Prev); + return getPointer()->find_next(Prev); } /// clear - Clear all bits. void clear() { if (!isSmall()) - delete X.getPointer(); + delete getPointer(); switchToSmall(0, 0); } /// resize - Grow or shrink the bitvector. void resize(unsigned N, bool t = false) { if (!isSmall()) { - X.getPointer()->resize(N, t); - } else if (getSmallSize() >= N) { + getPointer()->resize(N, t); + } else if (SmallNumDataBits >= N) { + uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0; setSmallSize(N); - setSmallBits(getSmallBits()); + setSmallBits(NewBits | getSmallBits()); } else { BitVector *BV = new BitVector(N, t); uintptr_t OldBits = getSmallBits(); @@ -224,7 +265,7 @@ public: switchToLarge(BV); } } else { - X.getPointer()->reserve(N); + getPointer()->reserve(N); } } @@ -233,7 +274,7 @@ public: if (isSmall()) setSmallBits(~uintptr_t(0)); else - X.getPointer()->set(); + getPointer()->set(); return *this; } @@ -241,7 +282,7 @@ public: if (isSmall()) setSmallBits(getSmallBits() | (uintptr_t(1) << Idx)); else - X.getPointer()->set(Idx); + getPointer()->set(Idx); return *this; } @@ -249,7 +290,7 @@ public: if (isSmall()) setSmallBits(0); else - X.getPointer()->reset(); + getPointer()->reset(); return *this; } @@ -257,7 +298,7 @@ public: if (isSmall()) setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); else - X.getPointer()->reset(Idx); + getPointer()->reset(Idx); return *this; } @@ -265,7 +306,7 @@ public: if (isSmall()) setSmallBits(~getSmallBits()); else - X.getPointer()->flip(); + getPointer()->flip(); return *this; } @@ -273,7 +314,7 @@ public: if (isSmall()) setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); else - X.getPointer()->flip(Idx); + getPointer()->flip(Idx); return *this; } @@ -283,12 +324,16 @@ public: } // Indexing. - // TODO: Add an index operator which returns a "reference" (proxy class). + reference operator[](unsigned Idx) { + assert(Idx < size() && "Out-of-bounds Bit access."); + return reference(*this, Idx); + } + bool operator[](unsigned Idx) const { assert(Idx < size() && "Out-of-bounds Bit access."); if (isSmall()) return ((getSmallBits() >> Idx) & 1) != 0; - return X.getPointer()->operator[](Idx); + return getPointer()->operator[](Idx); } bool test(unsigned Idx) const { @@ -302,7 +347,7 @@ public: if (isSmall()) return getSmallBits() == RHS.getSmallBits(); else - return *X.getPointer() == *RHS.X.getPointer(); + return *getPointer() == *RHS.getPointer(); } bool operator!=(const SmallBitVector &RHS) const { @@ -315,11 +360,11 @@ public: if (isSmall()) setSmallBits(getSmallBits() & RHS.getSmallBits()); else if (!RHS.isSmall()) - X.getPointer()->operator&=(*RHS.X.getPointer()); + getPointer()->operator&=(*RHS.getPointer()); else { SmallBitVector Copy = RHS; Copy.resize(size()); - X.getPointer()->operator&=(*Copy.X.getPointer()); + getPointer()->operator&=(*Copy.getPointer()); } return *this; } @@ -329,11 +374,11 @@ public: if (isSmall()) setSmallBits(getSmallBits() | RHS.getSmallBits()); else if (!RHS.isSmall()) - X.getPointer()->operator|=(*RHS.X.getPointer()); + getPointer()->operator|=(*RHS.getPointer()); else { SmallBitVector Copy = RHS; Copy.resize(size()); - X.getPointer()->operator|=(*Copy.X.getPointer()); + getPointer()->operator|=(*Copy.getPointer()); } return *this; } @@ -343,11 +388,11 @@ public: if (isSmall()) setSmallBits(getSmallBits() ^ RHS.getSmallBits()); else if (!RHS.isSmall()) - X.getPointer()->operator^=(*RHS.X.getPointer()); + getPointer()->operator^=(*RHS.getPointer()); else { SmallBitVector Copy = RHS; Copy.resize(size()); - X.getPointer()->operator^=(*Copy.X.getPointer()); + getPointer()->operator^=(*Copy.getPointer()); } return *this; } @@ -358,12 +403,12 @@ public: if (RHS.isSmall()) X = RHS.X; else - switchToLarge(new BitVector(*RHS.X.getPointer())); + switchToLarge(new BitVector(*RHS.getPointer())); } else { if (!RHS.isSmall()) - *X.getPointer() = *RHS.X.getPointer(); + *getPointer() = *RHS.getPointer(); else { - delete X.getPointer(); + delete getPointer(); X = RHS.X; } } diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 2d79a02..18c8619 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -59,7 +59,7 @@ protected: // number of union instances for the space, which guarantee maximal alignment. struct U { #ifdef __GNUC__ - char X __attribute__((aligned)); + char X __attribute__((aligned(8))); #else union { double D; diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 1ea546f..3c53ade 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -57,15 +57,14 @@ static inline char *utohex_buffer(IntTy X, char *BufferEnd) { } static inline std::string utohexstr(uint64_t X) { - char Buffer[40]; - return utohex_buffer(X, Buffer+40); + char Buffer[17]; + return utohex_buffer(X, Buffer+17); } static inline std::string utostr_32(uint32_t X, bool isNeg = false) { - char Buffer[20]; - char *BufPtr = Buffer+19; + char Buffer[11]; + char *BufPtr = Buffer+11; - *BufPtr = 0; // Null terminate buffer... if (X == 0) *--BufPtr = '0'; // Handle special case... while (X) { @@ -75,17 +74,13 @@ static inline std::string utostr_32(uint32_t X, bool isNeg = false) { if (isNeg) *--BufPtr = '-'; // Add negative sign... - return std::string(BufPtr); + return std::string(BufPtr, Buffer+11); } static inline std::string utostr(uint64_t X, bool isNeg = false) { - if (X == uint32_t(X)) - return utostr_32(uint32_t(X), isNeg); + char Buffer[21]; + char *BufPtr = Buffer+21; - char Buffer[40]; - char *BufPtr = Buffer+39; - - *BufPtr = 0; // Null terminate buffer... if (X == 0) *--BufPtr = '0'; // Handle special case... while (X) { @@ -94,7 +89,7 @@ static inline std::string utostr(uint64_t X, bool isNeg = false) { } if (isNeg) *--BufPtr = '-'; // Add negative sign... - return std::string(BufPtr); + return std::string(BufPtr, Buffer+21); } diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 9257770..ab6358b 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -44,8 +44,8 @@ namespace llvm { // Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min() // Changing the arg of min to be an integer, instead of a reference to an // integer works around this bug. - size_t min(size_t a, size_t b) const { return a < b ? a : b; } - size_t max(size_t a, size_t b) const { return a > b ? a : b; } + static size_t min(size_t a, size_t b) { return a < b ? a : b; } + static size_t max(size_t a, size_t b) { return a > b ? a : b; } public: /// @name Constructors diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 287fe4f..a4884ed 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -187,6 +187,9 @@ public: // CallGraphNode ctor - Create a node for the specified function. inline CallGraphNode(Function *f) : F(f), NumReferences(0) {} + ~CallGraphNode() { + assert(NumReferences == 0 && "Node deleted while references remain"); + } //===--------------------------------------------------------------------- // Accessor methods. @@ -277,6 +280,11 @@ public: /// time, so it should be used sparingly. void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode); + /// allReferencesDropped - This is a special function that should only be + /// used by the CallGraph class. + void allReferencesDropped() { + NumReferences = 0; + } }; //===----------------------------------------------------------------------===// diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index d68bfa3..9b1379d 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -392,6 +392,7 @@ namespace llvm { return getFieldAs<DICompositeType>(13); } unsigned isArtificial() const { return getUnsignedField(14); } + unsigned isOptimized() const; StringRef getFilename() const { if (getVersion() == llvm::LLVMDebugVersion7) @@ -474,6 +475,10 @@ namespace llvm { return getType().isBlockByrefStruct(); } + /// isInlinedFnArgument - Return trule if this variable provides debugging + /// information for an inlined function arguments. + bool isInlinedFnArgument(const Function *CurFn); + /// dump - print variable. void dump() const; }; @@ -638,7 +643,8 @@ namespace llvm { unsigned VK = 0, unsigned VIndex = 0, DIType = DIType(), - bool isArtificial = 0); + bool isArtificial = 0, + bool isOptimized = false); /// CreateSubprogramDefinition - Create new subprogram descriptor for the /// given declaration. diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index dc616ca..578e6ab 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -16,6 +16,7 @@ #define LLVM_ANALYSIS_IVUSERS_H #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/ScalarEvolutionNormalization.h" #include "llvm/Support/ValueHandle.h" namespace llvm { @@ -26,17 +27,17 @@ class Value; class IVUsers; class ScalarEvolution; class SCEV; +class IVUsers; /// IVStrideUse - Keep track of one use of a strided induction variable. /// The Expr member keeps track of the expression, User is the actual user /// instruction of the operand, and 'OperandValToReplace' is the operand of /// the User that is the use. class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { + friend class IVUsers; public: - IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off, - Instruction* U, Value *O) - : CallbackVH(U), Parent(P), Stride(S), Offset(Off), - OperandValToReplace(O), IsUseOfPostIncrementedValue(false) { + IVStrideUse(IVUsers *P, Instruction* U, Value *O) + : CallbackVH(U), Parent(P), OperandValToReplace(O) { } /// getUser - Return the user instruction for this use. @@ -49,28 +50,6 @@ public: setValPtr(NewUser); } - /// getParent - Return a pointer to the IVUsers that owns - /// this IVStrideUse. - IVUsers *getParent() const { return Parent; } - - /// getStride - Return the expression for the stride for the use. - const SCEV *getStride() const { return Stride; } - - /// setStride - Assign a new stride to this use. - void setStride(const SCEV *Val) { - Stride = Val; - } - - /// getOffset - Return the offset to add to a theoretical induction - /// variable that starts at zero and counts up by the stride to compute - /// the value for the use. This always has the same type as the stride. - const SCEV *getOffset() const { return Offset; } - - /// setOffset - Assign a new offset to this use. - void setOffset(const SCEV *Val) { - Offset = Val; - } - /// getOperandValToReplace - Return the Value of the operand in the user /// instruction that this IVStrideUse is representing. Value *getOperandValToReplace() const { @@ -83,37 +62,27 @@ public: OperandValToReplace = Op; } - /// isUseOfPostIncrementedValue - True if this should use the - /// post-incremented version of this IV, not the preincremented version. - /// This can only be set in special cases, such as the terminating setcc - /// instruction for a loop or uses dominated by the loop. - bool isUseOfPostIncrementedValue() const { - return IsUseOfPostIncrementedValue; + /// getPostIncLoops - Return the set of loops for which the expression has + /// been adjusted to use post-inc mode. + const PostIncLoopSet &getPostIncLoops() const { + return PostIncLoops; } - /// setIsUseOfPostIncrmentedValue - set the flag that indicates whether - /// this is a post-increment use. - void setIsUseOfPostIncrementedValue(bool Val) { - IsUseOfPostIncrementedValue = Val; - } + /// transformToPostInc - Transform the expression to post-inc form for the + /// given loop. + void transformToPostInc(const Loop *L); private: /// Parent - a pointer to the IVUsers that owns this IVStrideUse. IVUsers *Parent; - /// Stride - The stride for this use. - const SCEV *Stride; - - /// Offset - The offset to add to the base induction expression. - const SCEV *Offset; - /// OperandValToReplace - The Value of the operand in the user instruction /// that this IVStrideUse is representing. WeakVH OperandValToReplace; - /// IsUseOfPostIncrementedValue - True if this should use the - /// post-incremented version of this IV, not the preincremented version. - bool IsUseOfPostIncrementedValue; + /// PostIncLoops - The set of loops for which Expr has been adjusted to + /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. + PostIncLoopSet PostIncLoops; /// Deleted - Implementation of CallbackVH virtual function to /// receive notification when the User is deleted. @@ -174,17 +143,16 @@ public: /// return true. Otherwise, return false. bool AddUsersIfInteresting(Instruction *I); - IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset, - Instruction *User, Value *Operand); + IVStrideUse &AddUser(Instruction *User, Value *Operand); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. - const SCEV *getReplacementExpr(const IVStrideUse &U) const; + const SCEV *getReplacementExpr(const IVStrideUse &IU) const; + + /// getExpr - Return the expression for the use. + const SCEV *getExpr(const IVStrideUse &IU) const; - /// getCanonicalExpr - Return a SCEV expression which computes the - /// value of the SCEV of the given IVStrideUse, ignoring the - /// isUseOfPostIncrementedValue flag. - const SCEV *getCanonicalExpr(const IVStrideUse &U) const; + const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const; typedef ilist<IVStrideUse>::iterator iterator; typedef ilist<IVStrideUse>::const_iterator const_iterator; diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index a0c521d..d51dd6c 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -1,4 +1,4 @@ -//===- InlineCost.cpp - Cost analysis for inliner ---------------*- C++ -*-===// +//===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,9 +16,9 @@ #include <cassert> #include <climits> -#include <map> #include <vector> #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ValueMap.h" namespace llvm { @@ -165,7 +165,9 @@ namespace llvm { void analyzeFunction(Function *F); }; - std::map<const Function *, FunctionInfo> CachedFunctionInfo; + // The Function* for a function can be changed (by ArgumentPromotion); + // the ValueMap will update itself when this happens. + ValueMap<const Function *, FunctionInfo> CachedFunctionInfo; public: @@ -174,6 +176,14 @@ namespace llvm { /// InlineCost getInlineCost(CallSite CS, SmallPtrSet<const Function *, 16> &NeverInline); + /// getCalledFunction - The heuristic used to determine if we should inline + /// the function call or not. The callee is explicitly specified, to allow + /// you to calculate the cost of inlining a function via a pointer. The + /// result assumes that the inlined version will always be used. You should + /// weight it yourself in cases where this callee will not always be called. + InlineCost getInlineCost(CallSite CS, + Function *Callee, + SmallPtrSet<const Function *, 16> &NeverInline); /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a /// higher threshold to determine if the function call should be inlined. @@ -189,6 +199,10 @@ namespace llvm { /// eliminated. void growCachedCostInfo(Function* Caller, Function* Callee); }; + + /// callIsSmall - If a call is likely to lower to a single target instruction, + /// or is otherwise deemed small return true. + bool callIsSmall(const Function *Callee); } #endif diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 13314e6..f47e740 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -46,6 +46,10 @@ namespace llvm { Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const TargetData *TD = 0); + /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold + /// the result. If not, this returns null. + Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, + const TargetData *TD = 0); /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h new file mode 100644 index 0000000..2f01366 --- /dev/null +++ b/include/llvm/Analysis/Lint.h @@ -0,0 +1,52 @@ +//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- 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 lint interfaces that can be used for some sanity checking +// of input to the system, and for checking that transformations +// haven't done something bad. In contrast to the Verifier, the Lint checker +// checks for undefined behavior or constructions with likely unintended +// behavior. +// +// To see what specifically is checked, look at Lint.cpp +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LINT_H +#define LLVM_ANALYSIS_LINT_H + +#include <string> + +namespace llvm { + +class FunctionPass; +class Module; +class Function; + +/// @brief Create a lint pass. +/// +/// Check a module or function. +FunctionPass *createLintPass(); + +/// @brief Check a module. +/// +/// This should only be used for debugging, because it plays games with +/// PassManagers and stuff. +void lintModule( + const Module &M, ///< The module to be checked + std::string *ErrorInfo = 0 ///< Information about failures. +); + +// lintFunction - Check a function. +void lintFunction( + const Function &F ///< The function to be checked +); + +} // End llvm namespace + +#endif diff --git a/include/llvm/Analysis/PointerTracking.h b/include/llvm/Analysis/PointerTracking.h index a14bbf0..6c4f838 100644 --- a/include/llvm/Analysis/PointerTracking.h +++ b/include/llvm/Analysis/PointerTracking.h @@ -27,7 +27,7 @@ #ifndef LLVM_ANALYSIS_POINTERTRACKING_H #define LLVM_ANALYSIS_POINTERTRACKING_H -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index ab13a9d..d3a8d8f 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -351,7 +351,8 @@ namespace llvm { /// (which may not be an immediate predecessor) which has exactly one /// successor from which BB is reachable, or null if no such block is /// found. - BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); + std::pair<BasicBlock *, BasicBlock *> + getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); /// isImpliedCond - Test whether the condition described by Pred, LHS, /// and RHS is true whenever the given Cond value evaluates to true. @@ -380,6 +381,13 @@ namespace llvm { Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs, const Loop *L); + /// isKnownPredicateWithRanges - Test if the given expression is known to + /// satisfy the condition described by Pred and the known constant ranges + /// of LHS and RHS. + /// + bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS); + public: static char ID; // Pass identification, replacement for typeid ScalarEvolution(); @@ -554,11 +562,11 @@ namespace llvm { /// getSCEVAtScope(getSCEV(V), L). const SCEV *getSCEVAtScope(Value *V, const Loop *L); - /// isLoopGuardedByCond - Test whether entry to the loop is protected by - /// a conditional between LHS and RHS. This is used to help avoid max + /// isLoopEntryGuardedByCond - Test whether entry to the loop is protected + /// by a conditional between LHS and RHS. This is used to help avoid max /// expressions in loop trip counts, and to eliminate casts. - bool isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, - const SCEV *LHS, const SCEV *RHS); + bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS); /// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is /// protected by a conditional between LHS and RHS. This is used to @@ -636,12 +644,21 @@ namespace llvm { /// bool isKnownNonZero(const SCEV *S); - /// isKnownNonZero - Test if the given expression is known to satisfy + /// isKnownPredicate - Test if the given expression is known to satisfy /// the condition described by Pred, LHS, and RHS. /// bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); + /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with + /// predicate Pred. Return true iff any changes were made. If the + /// operands are provably equal or inequal, LHS and RHS are set to + /// the same value and Pred is set to either ICMP_EQ or ICMP_NE. + /// + bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, + const SCEV *&LHS, + const SCEV *&RHS); + virtual bool runOnFunction(Function &F); virtual void releaseMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index dc9b73b..baf6946 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -15,6 +15,7 @@ #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ScalarEvolutionNormalization.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/TargetFolder.h" #include <set> @@ -32,12 +33,12 @@ namespace llvm { InsertedExpressions; std::set<Value*> InsertedValues; - /// PostIncLoop - When non-null, expanded addrecs referring to the given - /// loop expanded in post-inc mode. For example, expanding {1,+,1}<L> in - /// post-inc mode returns the add instruction that adds one to the phi - /// for {0,+,1}<L>, as opposed to a new phi starting at 1. This is only - /// supported in non-canonical mode. - const Loop *PostIncLoop; + /// PostIncLoops - Addrecs referring to any of the given loops are expanded + /// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode + /// returns the add instruction that adds one to the phi for {0,+,1}<L>, + /// as opposed to a new phi starting at 1. This is only supported in + /// non-canonical mode. + PostIncLoopSet PostIncLoops; /// IVIncInsertPos - When this is non-null, addrecs expanded in the /// loop it indicates should be inserted with increments at @@ -62,7 +63,7 @@ namespace llvm { public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. explicit SCEVExpander(ScalarEvolution &se) - : SE(se), PostIncLoop(0), IVIncInsertLoop(0), CanonicalMode(true), + : SE(se), IVIncInsertLoop(0), CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {} /// clear - Erase the contents of the InsertedExpressions map so that users @@ -89,14 +90,18 @@ namespace llvm { IVIncInsertPos = Pos; } - /// setPostInc - If L is non-null, enable post-inc expansion for addrecs - /// referring to the given loop. If L is null, disable post-inc expansion - /// completely. Post-inc expansion is only supported in non-canonical + /// setPostInc - Enable post-inc expansion for addrecs referring to the + /// given loops. Post-inc expansion is only supported in non-canonical /// mode. - void setPostInc(const Loop *L) { + void setPostInc(const PostIncLoopSet &L) { assert(!CanonicalMode && "Post-inc expansion is not supported in CanonicalMode"); - PostIncLoop = L; + PostIncLoops = L; + } + + /// clearPostInc - Disable all post-inc expansion. + void clearPostInc() { + PostIncLoops.clear(); } /// disableCanonicalMode - Disable the behavior of expanding expressions in diff --git a/include/llvm/Analysis/ScalarEvolutionNormalization.h b/include/llvm/Analysis/ScalarEvolutionNormalization.h new file mode 100644 index 0000000..342e5937 --- /dev/null +++ b/include/llvm/Analysis/ScalarEvolutionNormalization.h @@ -0,0 +1,78 @@ +//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- 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 utilities for working with "normalized" ScalarEvolution +// expressions. +// +// The following example illustrates post-increment uses and how normalized +// expressions help. +// +// for (i=0; i!=n; ++i) { +// ... +// } +// use(i); +// +// While the expression for most uses of i inside the loop is {0,+,1}<%L>, the +// expression for the use of i outside the loop is {1,+,1}<%L>, since i is +// incremented at the end of the loop body. This is inconveient, since it +// suggests that we need two different induction variables, one that starts +// at 0 and one that starts at 1. We'd prefer to be able to think of these as +// the same induction variable, with uses inside the loop using the +// "pre-incremented" value, and uses after the loop using the +// "post-incremented" value. +// +// Expressions for post-incremented uses are represented as an expression +// paired with a set of loops for which the expression is in "post-increment" +// mode (there may be multiple loops). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H +#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H + +#include "llvm/ADT/SmallPtrSet.h" + +namespace llvm { + +class Instruction; +class DominatorTree; +class Loop; +class ScalarEvolution; +class SCEV; +class Value; + +/// TransformKind - Different types of transformations that +/// TransformForPostIncUse can do. +enum TransformKind { + /// Normalize - Normalize according to the given loops. + Normalize, + /// NormalizeAutodetect - Detect post-inc opportunities on new expressions, + /// update the given loop set, and normalize. + NormalizeAutodetect, + /// Denormalize - Perform the inverse transform on the expression with the + /// given loop set. + Denormalize +}; + +/// PostIncLoopSet - A set of loops. +typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet; + +/// TransformForPostIncUse - Transform the given expression according to the +/// given transformation kind. +const SCEV *TransformForPostIncUse(TransformKind Kind, + const SCEV *S, + Instruction *User, + Value *OperandValToReplace, + PostIncLoopSet &Loops, + ScalarEvolution &SE, + DominatorTree &DT); + +} + +#endif diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 0791b7b..d580897 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -122,7 +122,8 @@ namespace llvm { /// StopAtNul is set to true (the default), the returned string is truncated /// by a nul character in the global. If StopAtNul is false, the nul /// character is included in the result string. - bool GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0, + bool GetConstantStringInfo(const Value *V, std::string &Str, + uint64_t Offset = 0, bool StopAtNul = true); /// GetStringLength - If we can compute the length of the string pointed to by diff --git a/include/llvm/Analysis/Verifier.h b/include/llvm/Analysis/Verifier.h index a6b2a6d..ce8aeef 100644 --- a/include/llvm/Analysis/Verifier.h +++ b/include/llvm/Analysis/Verifier.h @@ -1,4 +1,4 @@ -//===-- llvm/Analysis/Verifier.h - Module Verifier --------------*- C++ -*-===// +//===-- llvm/Analysis/Verifier.h - LLVM IR Verifier -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h index 67f2a4a..83a3758 100644 --- a/include/llvm/Bitcode/Archive.h +++ b/include/llvm/Bitcode/Archive.h @@ -107,7 +107,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> { /// into memory, the return value will be null. /// @returns a pointer to the member's data. /// @brief Get the data content of the archive member - const void* getData() const { return data; } + const char* getData() const { return data; } /// This method determines if the member is a regular compressed file. /// @returns true iff the archive member is a compressed regular file. @@ -172,7 +172,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> { sys::PathWithStatus path; ///< Path of file containing the member sys::FileStatus info; ///< Status info (size,mode,date) unsigned flags; ///< Flags about the archive member - const void* data; ///< Data for the member + const char* data; ///< Data for the member /// @} /// @name Constructors diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/CallGraphSCCPass.h index 37a454e..e11b967 100644 --- a/include/llvm/CallGraphSCCPass.h +++ b/include/llvm/CallGraphSCCPass.h @@ -29,9 +29,10 @@ namespace llvm { class CallGraphNode; class CallGraph; class PMStack; - -struct CallGraphSCCPass : public Pass { - +class CallGraphSCC; + +class CallGraphSCCPass : public Pass { +public: explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {} explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {} @@ -53,7 +54,7 @@ struct CallGraphSCCPass : public Pass { /// SCC passes that add or delete functions to the SCC are required to update /// the SCC list, otherwise stale pointers may be dereferenced. /// - virtual bool runOnSCC(std::vector<CallGraphNode *> &SCC) = 0; + virtual bool runOnSCC(CallGraphSCC &SCC) = 0; /// doFinalization - This method is called after the SCC's of the program has /// been processed, allowing the pass to do final cleanup as necessary. @@ -63,7 +64,7 @@ struct CallGraphSCCPass : public Pass { /// Assign pass manager to manager this pass virtual void assignPassManager(PMStack &PMS, - PassManagerType PMT = PMT_CallGraphPassManager); + PassManagerType PMT =PMT_CallGraphPassManager); /// Return what kind of Pass Manager can manage this pass. virtual PassManagerType getPotentialPassManagerType() const { @@ -76,6 +77,29 @@ struct CallGraphSCCPass : public Pass { virtual void getAnalysisUsage(AnalysisUsage &Info) const; }; +/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. +class CallGraphSCC { + void *Context; // The CGPassManager object that is vending this. + std::vector<CallGraphNode*> Nodes; +public: + CallGraphSCC(void *context) : Context(context) {} + + void initialize(CallGraphNode*const*I, CallGraphNode*const*E) { + Nodes.assign(I, E); + } + + bool isSingular() const { return Nodes.size() == 1; } + unsigned size() const { return Nodes.size(); } + + /// ReplaceNode - This informs the SCC and the pass manager that the specified + /// Old node has been deleted, and New is to be used in its place. + void ReplaceNode(CallGraphNode *Old, CallGraphNode *New); + + typedef std::vector<CallGraphNode*>::const_iterator iterator; + iterator begin() const { return Nodes.begin(); } + iterator end() const { return Nodes.end(); } +}; + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h new file mode 100644 index 0000000..f33a9db --- /dev/null +++ b/include/llvm/CodeGen/Analysis.h @@ -0,0 +1,80 @@ +//===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares several CodeGen-specific LLVM IR analysis utilties. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ANALYSIS_H +#define LLVM_CODEGEN_ANALYSIS_H + +#include "llvm/Instructions.h" +#include "llvm/InlineAsm.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/Support/CallSite.h" + +namespace llvm { + +class TargetLowering; +class GlobalVariable; + +/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence +/// of insertvalue or extractvalue indices that identify a member, return +/// the linearized index of the start of the member. +/// +unsigned ComputeLinearIndex(const TargetLowering &TLI, const Type *Ty, + const unsigned *Indices, + const unsigned *IndicesEnd, + unsigned CurIndex = 0); + +/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of +/// EVTs that represent all the individual underlying +/// non-aggregate types that comprise it. +/// +/// If Offsets is non-null, it points to a vector to be filled in +/// with the in-memory offsets of each of the individual values. +/// +void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty, + SmallVectorImpl<EVT> &ValueVTs, + SmallVectorImpl<uint64_t> *Offsets = 0, + uint64_t StartingOffset = 0); + +/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V. +GlobalVariable *ExtractTypeInfo(Value *V); + +/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being +/// processed uses a memory 'm' constraint. +bool hasInlineAsmMemConstraint(std::vector<InlineAsm::ConstraintInfo> &CInfos, + const TargetLowering &TLI); + +/// getFCmpCondCode - Return the ISD condition code corresponding to +/// the given LLVM IR floating-point condition code. This includes +/// consideration of global floating-point math flags. +/// +ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred); + +/// getICmpCondCode - Return the ISD condition code corresponding to +/// the given LLVM IR integer condition code. +/// +ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred); + +/// Test if the given instruction is in a position to be optimized +/// with a tail-call. This roughly means that it's in a block with +/// a return and there's nothing that needs to be scheduled +/// between it and the return. +/// +/// This function only tests target-independent requirements. +bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr, + const TargetLowering &TLI); + +} // End llvm namespace + +#endif diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 2eff501..243ddbb 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -34,6 +34,7 @@ namespace llvm { class MachineBasicBlock; class MachineFunction; class MachineInstr; + class MachineLocation; class MachineLoopInfo; class MachineLoop; class MachineConstantPool; @@ -129,7 +130,7 @@ namespace llvm { unsigned getFunctionNumber() const; /// getObjFileLowering - Return information about object file lowering. - TargetLoweringObjectFile &getObjFileLowering() const; + const TargetLoweringObjectFile &getObjFileLowering() const; /// getTargetData - Return information about data layout. const TargetData &getTargetData() const; @@ -203,29 +204,16 @@ namespace llvm { /// EmitAlignment - Emit an alignment directive to the specified power of /// two boundary. For example, if you pass in 3 here, you will get an 8 /// byte alignment. If a global value is specified, and if that global has - /// an explicit alignment requested, it will unconditionally override the - /// alignment request. However, if ForcedAlignBits is specified, this value - /// has final say: the ultimate alignment will be the max of ForcedAlignBits - /// and the alignment computed with NumBits and the global. If UseFillExpr - /// is true, it also emits an optional second value FillValue which the - /// assembler uses to fill gaps to match alignment for text sections if the - /// has specified a non-zero fill value. + /// an explicit alignment requested, it will override the alignment request + /// if required for correctness. /// - /// The algorithm is: - /// Align = NumBits; - /// if (GV && GV->hasalignment) Align = GV->getalignment(); - /// Align = std::max(Align, ForcedAlignBits); - /// - void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0, - unsigned ForcedAlignBits = 0, - bool UseFillExpr = true) const; + void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing /// it if appropriate. void EmitBasicBlockStart(const MachineBasicBlock *MBB) const; - /// EmitGlobalConstant - Print a general LLVM constant to the .s file. void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0); @@ -333,6 +321,12 @@ namespace llvm { void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const; + /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" + /// where the size in bytes of the directive is specified by Size and Hi/Lo + /// specify the labels. This implicitly uses .set if it is available. + void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, + const MCSymbol *Lo, unsigned Size) const; + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// @@ -370,7 +364,11 @@ namespace llvm { /// that Label lives in. void EmitSectionOffset(const MCSymbol *Label, const MCSymbol *SectionLabel) const; - + + /// getDebugValueLocation - Get location information encoded by DBG_VALUE + /// operands. + virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; + //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 8d33665..5a2b0e7 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -15,8 +15,10 @@ #define LLVM_CODEGEN_FASTISEL_H #include "llvm/ADT/DenseMap.h" +#ifndef NDEBUG #include "llvm/ADT/SmallSet.h" -#include "llvm/CodeGen/SelectionDAGNodes.h" +#endif +#include "llvm/CodeGen/ValueTypes.h" namespace llvm { @@ -26,6 +28,7 @@ class Instruction; class MachineBasicBlock; class MachineConstantPool; class MachineFunction; +class MachineInstr; class MachineFrameInfo; class MachineRegisterInfo; class TargetData; @@ -44,8 +47,9 @@ protected: DenseMap<const Value *, unsigned> &ValueMap; DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap; DenseMap<const AllocaInst *, int> &StaticAllocaMap; + std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate; #ifndef NDEBUG - SmallSet<Instruction*, 8> &CatchInfoLost; + SmallSet<const Instruction *, 8> &CatchInfoLost; #endif MachineFunction &MF; MachineRegisterInfo &MRI; @@ -73,11 +77,6 @@ public: MBB = mbb; } - /// setCurDebugLoc - Set the current debug location information, which is used - /// when creating a machine instruction. - /// - void setCurDebugLoc(DebugLoc dl) { DL = dl; } - /// getCurDebugLoc() - Return current debug location information. DebugLoc getCurDebugLoc() const { return DL; } @@ -85,28 +84,28 @@ public: /// LLVM IR instruction, and append generated machine instructions to /// the current block. Return true if selection was successful. /// - bool SelectInstruction(Instruction *I); + bool SelectInstruction(const Instruction *I); /// SelectOperator - Do "fast" instruction selection for the given /// LLVM IR operator (Instruction or ConstantExpr), and append /// generated machine instructions to the current block. Return true /// if selection was successful. /// - bool SelectOperator(User *I, unsigned Opcode); + bool SelectOperator(const User *I, unsigned Opcode); /// getRegForValue - Create a virtual register and arrange for it to /// be assigned the value for the given LLVM value. - unsigned getRegForValue(Value *V); + unsigned getRegForValue(const Value *V); /// lookUpRegForValue - Look up the value to see if its value is already /// cached in a register. It may be defined by instructions across blocks or /// defined locally. - unsigned lookUpRegForValue(Value *V); + unsigned lookUpRegForValue(const Value *V); /// getRegForGEPIndex - This is a wrapper around getRegForValue that also /// takes care of truncating or sign-extending the given getelementptr /// index value. - unsigned getRegForGEPIndex(Value *V); + unsigned getRegForGEPIndex(const Value *V); virtual ~FastISel(); @@ -114,9 +113,10 @@ protected: FastISel(MachineFunction &mf, DenseMap<const Value *, unsigned> &vm, DenseMap<const BasicBlock *, MachineBasicBlock *> &bm, - DenseMap<const AllocaInst *, int> &am + DenseMap<const AllocaInst *, int> &am, + std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate #ifndef NDEBUG - , SmallSet<Instruction*, 8> &cil + , SmallSet<const Instruction *, 8> &cil #endif ); @@ -126,7 +126,7 @@ protected: /// fit into FastISel's framework. It returns true if it was successful. /// virtual bool - TargetSelectInstruction(Instruction *I) = 0; + TargetSelectInstruction(const Instruction *I) = 0; /// FastEmit_r - This method is called by target-independent code /// to request that an instruction with the given type and opcode @@ -168,7 +168,7 @@ protected: virtual unsigned FastEmit_rf(MVT VT, MVT RetVT, unsigned Opcode, - unsigned Op0, ConstantFP *FPImm); + unsigned Op0, const ConstantFP *FPImm); /// FastEmit_rri - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and @@ -194,7 +194,7 @@ protected: /// FastEmit_rr instead. unsigned FastEmit_rf_(MVT VT, unsigned Opcode, - unsigned Op0, ConstantFP *FPImm, + unsigned Op0, const ConstantFP *FPImm, MVT ImmType); /// FastEmit_i - This method is called by target-independent code @@ -211,7 +211,7 @@ protected: virtual unsigned FastEmit_f(MVT VT, MVT RetVT, unsigned Opcode, - ConstantFP *FPImm); + const ConstantFP *FPImm); /// FastEmitInst_ - Emit a MachineInstr with no operands and a /// result register in the given register class. @@ -245,7 +245,7 @@ protected: /// unsigned FastEmitInst_rf(unsigned MachineInstOpcode, const TargetRegisterClass *RC, - unsigned Op0, ConstantFP *FPImm); + unsigned Op0, const ConstantFP *FPImm); /// FastEmitInst_rri - Emit a MachineInstr with two register operands, /// an immediate, and a result register in the given register class. @@ -275,34 +275,47 @@ protected: /// the CFG. void FastEmitBranch(MachineBasicBlock *MBB); - unsigned UpdateValueMap(Value* I, unsigned Reg); + unsigned UpdateValueMap(const Value* I, unsigned Reg); unsigned createResultReg(const TargetRegisterClass *RC); /// TargetMaterializeConstant - Emit a constant in a register using /// target-specific logic, such as constant pool loads. - virtual unsigned TargetMaterializeConstant(Constant* C) { + virtual unsigned TargetMaterializeConstant(const Constant* C) { return 0; } /// TargetMaterializeAlloca - Emit an alloca address in a register using /// target-specific logic. - virtual unsigned TargetMaterializeAlloca(AllocaInst* C) { + virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) { return 0; } private: - bool SelectBinaryOp(User *I, unsigned ISDOpcode); + bool SelectBinaryOp(const User *I, unsigned ISDOpcode); - bool SelectFNeg(User *I); + bool SelectFNeg(const User *I); - bool SelectGetElementPtr(User *I); + bool SelectGetElementPtr(const User *I); - bool SelectCall(User *I); + bool SelectCall(const User *I); - bool SelectBitCast(User *I); + bool SelectBitCast(const User *I); - bool SelectCast(User *I, unsigned Opcode); + bool SelectCast(const User *I, unsigned Opcode); + + /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. + /// Emit code to ensure constants are copied into registers when needed. + /// Remember the virtual registers that need to be added to the Machine PHI + /// nodes as input. We cannot just directly add them, because expansion + /// might result in multiple MBB's for one BB. As such, the start of the + /// BB might correspond to a different MBB than the end. + bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); + + /// materializeRegForValue - Helper for getRegForVale. This function is + /// called when the value isn't already available in a register and must + /// be materialized with new instructions. + unsigned materializeRegForValue(const Value *V, MVT VT); }; } diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 783f636..6de69cd 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -68,9 +68,9 @@ namespace llvm { struct GCRoot { int Num; //< Usually a frame index. int StackOffset; //< Offset from the stack pointer. - Constant *Metadata; //< Metadata straight from the call to llvm.gcroot. + const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot. - GCRoot(int N, Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {} + GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {} }; @@ -114,7 +114,7 @@ namespace llvm { /// addStackRoot - Registers a root that lives on the stack. Num is the /// stack object ID for the alloca (if the code generator is // using MachineFrameInfo). - void addStackRoot(int Num, Constant *Metadata) { + void addStackRoot(int Num, const Constant *Metadata) { Roots.push_back(GCRoot(Num, Metadata)); } diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h new file mode 100644 index 0000000..ba554d3 --- /dev/null +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -0,0 +1,765 @@ +//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares codegen opcodes and related utilities. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ISDOPCODES_H +#define LLVM_CODEGEN_ISDOPCODES_H + +namespace llvm { + +/// ISD namespace - This namespace contains an enum which represents all of the +/// SelectionDAG node types and value types. +/// +namespace ISD { + + //===--------------------------------------------------------------------===// + /// ISD::NodeType enum - This enum defines the target-independent operators + /// for a SelectionDAG. + /// + /// Targets may also define target-dependent operator codes for SDNodes. For + /// example, on x86, these are the enum values in the X86ISD namespace. + /// Targets should aim to use target-independent operators to model their + /// instruction sets as much as possible, and only use target-dependent + /// operators when they have special requirements. + /// + /// Finally, during and after selection proper, SNodes may use special + /// operator codes that correspond directly with MachineInstr opcodes. These + /// are used to represent selected instructions. See the isMachineOpcode() + /// and getMachineOpcode() member functions of SDNode. + /// + enum NodeType { + // DELETED_NODE - This is an illegal value that is used to catch + // errors. This opcode is not a legal opcode for any node. + DELETED_NODE, + + // EntryToken - This is the marker used to indicate the start of the region. + EntryToken, + + // TokenFactor - This node takes multiple tokens as input and produces a + // single token result. This is used to represent the fact that the operand + // operators are independent of each other. + TokenFactor, + + // AssertSext, AssertZext - These nodes record if a register contains a + // value that has already been zero or sign extended from a narrower type. + // These nodes take two operands. The first is the node that has already + // been extended, and the second is a value type node indicating the width + // of the extension + AssertSext, AssertZext, + + // Various leaf nodes. + BasicBlock, VALUETYPE, CONDCODE, Register, + Constant, ConstantFP, + GlobalAddress, GlobalTLSAddress, FrameIndex, + JumpTable, ConstantPool, ExternalSymbol, BlockAddress, + + // The address of the GOT + GLOBAL_OFFSET_TABLE, + + // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and + // llvm.returnaddress on the DAG. These nodes take one operand, the index + // of the frame or return address to return. An index of zero corresponds + // to the current function's frame or return address, an index of one to the + // parent's frame or return address, and so on. + FRAMEADDR, RETURNADDR, + + // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to + // first (possible) on-stack argument. This is needed for correct stack + // adjustment during unwind. + FRAME_TO_ARGS_OFFSET, + + // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the + // address of the exception block on entry to an landing pad block. + EXCEPTIONADDR, + + // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the + // address of the Language Specific Data Area for the enclosing function. + LSDAADDR, + + // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents + // the selection index of the exception thrown. + EHSELECTION, + + // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents + // 'eh_return' gcc dwarf builtin, which is used to return from + // exception. The general meaning is: adjust stack by OFFSET and pass + // execution to HANDLER. Many platform-related details also :) + EH_RETURN, + + // TargetConstant* - Like Constant*, but the DAG does not do any folding, + // simplification, or lowering of the constant. They are used for constants + // which are known to fit in the immediate fields of their users, or for + // carrying magic numbers which are not values which need to be materialized + // in registers. + TargetConstant, + TargetConstantFP, + + // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or + // anything else with this node, and this is valid in the target-specific + // dag, turning into a GlobalAddress operand. + TargetGlobalAddress, + TargetGlobalTLSAddress, + TargetFrameIndex, + TargetJumpTable, + TargetConstantPool, + TargetExternalSymbol, + TargetBlockAddress, + + /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) + /// This node represents a target intrinsic function with no side effects. + /// The first operand is the ID number of the intrinsic from the + /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The + /// node has returns the result of the intrinsic. + INTRINSIC_WO_CHAIN, + + /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) + /// This node represents a target intrinsic function with side effects that + /// returns a result. The first operand is a chain pointer. The second is + /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The + /// operands to the intrinsic follow. The node has two results, the result + /// of the intrinsic and an output chain. + INTRINSIC_W_CHAIN, + + /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) + /// This node represents a target intrinsic function with side effects that + /// does not return a result. The first operand is a chain pointer. The + /// second is the ID number of the intrinsic from the llvm::Intrinsic + /// namespace. The operands to the intrinsic follow. + INTRINSIC_VOID, + + // CopyToReg - This node has three operands: a chain, a register number to + // set to this value, and a value. + CopyToReg, + + // CopyFromReg - This node indicates that the input value is a virtual or + // physical register that is defined outside of the scope of this + // SelectionDAG. The register is available from the RegisterSDNode object. + CopyFromReg, + + // UNDEF - An undefined node + UNDEF, + + // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by + // a Constant, which is required to be operand #1) half of the integer or + // float value specified as operand #0. This is only for use before + // legalization, for values that will be broken into multiple registers. + EXTRACT_ELEMENT, + + // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given + // two values of the same integer value type, this produces a value twice as + // big. Like EXTRACT_ELEMENT, this can only be used before legalization. + BUILD_PAIR, + + // MERGE_VALUES - This node takes multiple discrete operands and returns + // them all as its individual results. This nodes has exactly the same + // number of inputs and outputs. This node is useful for some pieces of the + // code generator that want to think about a single node with multiple + // results, not multiple nodes. + MERGE_VALUES, + + // Simple integer binary arithmetic operators. + ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, + + // SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing + // a signed/unsigned value of type i[2*N], and return the full value as + // two results, each of type iN. + SMUL_LOHI, UMUL_LOHI, + + // SDIVREM/UDIVREM - Divide two integers and produce both a quotient and + // remainder result. + SDIVREM, UDIVREM, + + // CARRY_FALSE - This node is used when folding other nodes, + // like ADDC/SUBC, which indicate the carry result is always false. + CARRY_FALSE, + + // Carry-setting nodes for multiple precision addition and subtraction. + // These nodes take two operands of the same value type, and produce two + // results. The first result is the normal add or sub result, the second + // result is the carry flag result. + ADDC, SUBC, + + // Carry-using nodes for multiple precision addition and subtraction. These + // nodes take three operands: The first two are the normal lhs and rhs to + // the add or sub, and the third is the input carry flag. These nodes + // produce two results; the normal result of the add or sub, and the output + // carry flag. These nodes both read and write a carry flag to allow them + // to them to be chained together for add and sub of arbitrarily large + // values. + ADDE, SUBE, + + // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. + // These nodes take two operands: the normal LHS and RHS to the add. They + // produce two results: the normal result of the add, and a boolean that + // indicates if an overflow occured (*not* a flag, because it may be stored + // to memory, etc.). If the type of the boolean is not i1 then the high + // bits conform to getBooleanContents. + // These nodes are generated from the llvm.[su]add.with.overflow intrinsics. + SADDO, UADDO, + + // Same for subtraction + SSUBO, USUBO, + + // Same for multiplication + SMULO, UMULO, + + // Simple binary floating point operators. + FADD, FSUB, FMUL, FDIV, FREM, + + // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This + // DAG node does not require that X and Y have the same type, just that they + // are both floating point. X and the result must have the same type. + // FCOPYSIGN(f32, f64) is allowed. + FCOPYSIGN, + + // INT = FGETSIGN(FP) - Return the sign bit of the specified floating point + // value as an integer 0/1 value. + FGETSIGN, + + /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the + /// specified, possibly variable, elements. The number of elements is + /// required to be a power of two. The types of the operands must all be + /// the same and must match the vector element type, except that integer + /// types are allowed to be larger than the element type, in which case + /// the operands are implicitly truncated. + BUILD_VECTOR, + + /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element + /// at IDX replaced with VAL. If the type of VAL is larger than the vector + /// element type then VAL is truncated before replacement. + INSERT_VECTOR_ELT, + + /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR + /// identified by the (potentially variable) element number IDX. If the + /// return type is an integer type larger than the element type of the + /// vector, the result is extended to the width of the return type. + EXTRACT_VECTOR_ELT, + + /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of + /// vector type with the same length and element type, this produces a + /// concatenated vector result value, with length equal to the sum of the + /// lengths of the input vectors. + CONCAT_VECTORS, + + /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an + /// vector value) starting with the (potentially variable) element number + /// IDX, which must be a multiple of the result vector length. + EXTRACT_SUBVECTOR, + + /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as + /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int + /// values that indicate which value (or undef) each result element will + /// get. These constant ints are accessible through the + /// ShuffleVectorSDNode class. This is quite similar to the Altivec + /// 'vperm' instruction, except that the indices must be constants and are + /// in terms of the element size of VEC1/VEC2, not in terms of bytes. + VECTOR_SHUFFLE, + + /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a + /// scalar value into element 0 of the resultant vector type. The top + /// elements 1 to N-1 of the N-element vector are undefined. The type + /// of the operand must match the vector element type, except when they + /// are integer types. In this case the operand is allowed to be wider + /// than the vector element type, and is implicitly truncated to it. + SCALAR_TO_VECTOR, + + // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing + // an unsigned/signed value of type i[2*N], then return the top part. + MULHU, MULHS, + + // Bitwise operators - logical and, logical or, logical xor, shift left, + // shift right algebraic (shift in sign bits), shift right logical (shift in + // zeroes), rotate left, rotate right, and byteswap. + AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP, + + // Counting operators + CTTZ, CTLZ, CTPOP, + + // Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not + // i1 then the high bits must conform to getBooleanContents. + SELECT, + + // Select with condition operator - This selects between a true value and + // a false value (ops #2 and #3) based on the boolean result of comparing + // the lhs and rhs (ops #0 and #1) of a conditional expression with the + // condition code in op #4, a CondCodeSDNode. + SELECT_CC, + + // SetCC operator - This evaluates to a true value iff the condition is + // true. If the result value type is not i1 then the high bits conform + // to getBooleanContents. The operands to this are the left and right + // operands to compare (ops #0, and #1) and the condition code to compare + // them with (op #2) as a CondCodeSDNode. + SETCC, + + // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of + // integer elements with all bits of the result elements set to true if the + // comparison is true or all cleared if the comparison is false. The + // operands to this are the left and right operands to compare (LHS/RHS) and + // the condition code to compare them with (COND) as a CondCodeSDNode. + VSETCC, + + // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded + // integer shift operations, just like ADD/SUB_PARTS. The operation + // ordering is: + // [Lo,Hi] = op [LoLHS,HiLHS], Amt + SHL_PARTS, SRA_PARTS, SRL_PARTS, + + // Conversion operators. These are all single input single output + // operations. For all of these, the result type must be strictly + // wider or narrower (depending on the operation) than the source + // type. + + // SIGN_EXTEND - Used for integer types, replicating the sign bit + // into new bits. + SIGN_EXTEND, + + // ZERO_EXTEND - Used for integer types, zeroing the new bits. + ZERO_EXTEND, + + // ANY_EXTEND - Used for integer types. The high bits are undefined. + ANY_EXTEND, + + // TRUNCATE - Completely drop the high bits. + TRUNCATE, + + // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign + // depends on the first letter) to floating point. + SINT_TO_FP, + UINT_TO_FP, + + // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to + // sign extend a small value in a large integer register (e.g. sign + // extending the low 8 bits of a 32-bit register to fill the top 24 bits + // with the 7th bit). The size of the smaller type is indicated by the 1th + // operand, a ValueType node. + SIGN_EXTEND_INREG, + + /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned + /// integer. + FP_TO_SINT, + FP_TO_UINT, + + /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type + /// down to the precision of the destination VT. TRUNC is a flag, which is + /// always an integer that is zero or one. If TRUNC is 0, this is a + /// normal rounding, if it is 1, this FP_ROUND is known to not change the + /// value of Y. + /// + /// The TRUNC = 1 case is used in cases where we know that the value will + /// not be modified by the node, because Y is not using any of the extra + /// precision of source type. This allows certain transformations like + /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for + /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed. + FP_ROUND, + + // FLT_ROUNDS_ - Returns current rounding mode: + // -1 Undefined + // 0 Round to 0 + // 1 Round to nearest + // 2 Round to +inf + // 3 Round to -inf + FLT_ROUNDS_, + + /// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and + /// rounds it to a floating point value. It then promotes it and returns it + /// in a register of the same size. This operation effectively just + /// discards excess precision. The type to round down to is specified by + /// the VT operand, a VTSDNode. + FP_ROUND_INREG, + + /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type. + FP_EXTEND, + + // 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 + // between various types (float, signed, unsigned and vectors of those + // types) with rounding and saturation. NOTE: Avoid using this operator as + // most target don't support it and the operator might be removed in the + // future. It takes the following arguments: + // 0) value + // 1) dest type (type to convert to) + // 2) src type (type to convert from) + // 3) rounding imm + // 4) saturation imm + // 5) ISD::CvtCode indicating the type of conversion to do + CONVERT_RNDSAT, + + // FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform + // promotions and truncation for half-precision (16 bit) floating + // numbers. We need special nodes since FP16 is a storage-only type with + // special semantics of operations. + FP16_TO_FP32, FP32_TO_FP16, + + // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, + // FLOG, FLOG2, FLOG10, FEXP, FEXP2, + // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating + // point operations. These are inspired by libm. + FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, + FLOG, FLOG2, FLOG10, FEXP, FEXP2, + FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR, + + // LOAD and STORE have token chains as their first operand, then the same + // operands as an LLVM load/store instruction, then an offset node that + // is added / subtracted from the base pointer to form the address (for + // indexed memory ops). + LOAD, STORE, + + // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned + // to a specified boundary. This node always has two return values: a new + // stack pointer value and a chain. The first operand is the token chain, + // the second is the number of bytes to allocate, and the third is the + // alignment boundary. The size is guaranteed to be a multiple of the stack + // alignment, and the alignment is guaranteed to be bigger than the stack + // alignment (if required) or 0 to get standard stack alignment. + DYNAMIC_STACKALLOC, + + // Control flow instructions. These all have token chains. + + // BR - Unconditional branch. The first operand is the chain + // operand, the second is the MBB to branch to. + BR, + + // BRIND - Indirect branch. The first operand is the chain, the second + // is the value to branch to, which must be of the same type as the target's + // pointer type. + BRIND, + + // BR_JT - Jumptable branch. The first operand is the chain, the second + // is the jumptable index, the last one is the jumptable entry index. + BR_JT, + + // BRCOND - Conditional branch. The first operand is the chain, the + // second is the condition, the third is the block to branch to if the + // condition is true. If the type of the condition is not i1, then the + // high bits must conform to getBooleanContents. + BRCOND, + + // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in + // that the condition is represented as condition code, and two nodes to + // compare, rather than as a combined SetCC node. The operands in order are + // chain, cc, lhs, rhs, block to branch to if condition is true. + BR_CC, + + // INLINEASM - Represents an inline asm block. This node always has two + // return values: a chain and a flag result. The inputs are as follows: + // Operand #0 : Input chain. + // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string. + // Operand #2 : a MDNodeSDNode with the !srcloc metadata. + // After this, it is followed by a list of operands with this format: + // ConstantSDNode: Flags that encode whether it is a mem or not, the + // of operands that follow, etc. See InlineAsm.h. + // ... however many operands ... + // Operand #last: Optional, an incoming flag. + // + // The variable width operands are required to represent target addressing + // modes as a single "operand", even though they may have multiple + // SDOperands. + INLINEASM, + + // EH_LABEL - Represents a label in mid basic block used to track + // locations needed for debug and exception handling tables. These nodes + // take a chain as input and return a chain. + EH_LABEL, + + // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a + // value, the same type as the pointer type for the system, and an output + // chain. + STACKSAVE, + + // STACKRESTORE has two operands, an input chain and a pointer to restore to + // it returns an output chain. + STACKRESTORE, + + // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of + // a call sequence, and carry arbitrary information that target might want + // to know. The first operand is a chain, the rest are specified by the + // target and not touched by the DAG optimizers. + // CALLSEQ_START..CALLSEQ_END pairs may not be nested. + CALLSEQ_START, // Beginning of a call sequence + CALLSEQ_END, // End of a call sequence + + // VAARG - VAARG has three operands: an input chain, a pointer, and a + // SRCVALUE. It returns a pair of values: the vaarg value and a new chain. + VAARG, + + // VACOPY - VACOPY has five operands: an input chain, a destination pointer, + // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the + // source. + VACOPY, + + // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a + // pointer, and a SRCVALUE. + VAEND, VASTART, + + // SRCVALUE - This is a node type that holds a Value* that is used to + // make reference to a value in the LLVM IR. + SRCVALUE, + + // MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to + // reference metadata in the IR. + MDNODE_SDNODE, + + // PCMARKER - This corresponds to the pcmarker intrinsic. + PCMARKER, + + // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic. + // The only operand is a chain and a value and a chain are produced. The + // value is the contents of the architecture specific cycle counter like + // register (or other high accuracy low latency clock source) + READCYCLECOUNTER, + + // HANDLENODE node - Used as a handle for various purposes. + HANDLENODE, + + // TRAMPOLINE - This corresponds to the init_trampoline intrinsic. + // It takes as input a token chain, the pointer to the trampoline, + // the pointer to the nested function, the pointer to pass for the + // 'nest' parameter, a SRCVALUE for the trampoline and another for + // the nested function (allowing targets to access the original + // Function*). It produces the result of the intrinsic and a token + // chain as output. + TRAMPOLINE, + + // TRAP - Trapping instruction + TRAP, + + // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are + // their first operand. The other operands are the address to prefetch, + // read / write specifier, and locality specifier. + PREFETCH, + + // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, + // store-store, device) + // This corresponds to the memory.barrier intrinsic. + // it takes an input chain, 4 operands to specify the type of barrier, an + // operand specifying if the barrier applies to device and uncached memory + // and produces an output chain. + MEMBARRIER, + + // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) + // this corresponds to the atomic.lcs intrinsic. + // cmp is compared to *ptr, and if equal, swap is stored in *ptr. + // the return is always the original value in *ptr + ATOMIC_CMP_SWAP, + + // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) + // this corresponds to the atomic.swap intrinsic. + // amt is stored to *ptr atomically. + // the return is always the original value in *ptr + ATOMIC_SWAP, + + // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) + // this corresponds to the atomic.load.[OpName] intrinsic. + // op(*ptr, amt) is stored to *ptr atomically. + // the return is always the original value in *ptr + ATOMIC_LOAD_ADD, + ATOMIC_LOAD_SUB, + ATOMIC_LOAD_AND, + ATOMIC_LOAD_OR, + ATOMIC_LOAD_XOR, + ATOMIC_LOAD_NAND, + ATOMIC_LOAD_MIN, + ATOMIC_LOAD_MAX, + ATOMIC_LOAD_UMIN, + ATOMIC_LOAD_UMAX, + + /// BUILTIN_OP_END - This must be the last enum value in this list. + /// The target-specific pre-isel opcode values start here. + BUILTIN_OP_END + }; + + /// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations + /// which do not reference a specific memory location should be less than + /// this value. Those that do must not be less than this value, and can + /// be used with SelectionDAG::getMemIntrinsicNode. + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100; + + //===--------------------------------------------------------------------===// + /// MemIndexedMode enum - This enum defines the load / store indexed + /// addressing modes. + /// + /// UNINDEXED "Normal" load / store. The effective address is already + /// computed and is available in the base pointer. The offset + /// operand is always undefined. In addition to producing a + /// chain, an unindexed load produces one value (result of the + /// load); an unindexed store does not produce a value. + /// + /// PRE_INC Similar to the unindexed mode where the effective address is + /// PRE_DEC the value of the base pointer add / subtract the offset. + /// It considers the computation as being folded into the load / + /// store operation (i.e. the load / store does the address + /// computation as well as performing the memory transaction). + /// The base operand is always undefined. In addition to + /// producing a chain, pre-indexed load produces two values + /// (result of the load and the result of the address + /// computation); a pre-indexed store produces one value (result + /// of the address computation). + /// + /// POST_INC The effective address is the value of the base pointer. The + /// POST_DEC value of the offset operand is then added to / subtracted + /// from the base after memory transaction. In addition to + /// producing a chain, post-indexed load produces two values + /// (the result of the load and the result of the base +/- offset + /// computation); a post-indexed store produces one value (the + /// the result of the base +/- offset computation). + /// + enum MemIndexedMode { + UNINDEXED = 0, + PRE_INC, + PRE_DEC, + POST_INC, + POST_DEC, + LAST_INDEXED_MODE + }; + + //===--------------------------------------------------------------------===// + /// LoadExtType enum - This enum defines the three variants of LOADEXT + /// (load with extension). + /// + /// SEXTLOAD loads the integer operand and sign extends it to a larger + /// integer result type. + /// ZEXTLOAD loads the integer operand and zero extends it to a larger + /// integer result type. + /// EXTLOAD is used for three things: floating point extending loads, + /// integer extending loads [the top bits are undefined], and vector + /// extending loads [load into low elt]. + /// + enum LoadExtType { + NON_EXTLOAD = 0, + EXTLOAD, + SEXTLOAD, + ZEXTLOAD, + LAST_LOADEXT_TYPE + }; + + //===--------------------------------------------------------------------===// + /// ISD::CondCode enum - These are ordered carefully to make the bitfields + /// below work out, when considering SETFALSE (something that never exists + /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered + /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal + /// to. If the "N" column is 1, the result of the comparison is undefined if + /// the input is a NAN. + /// + /// All of these (except for the 'always folded ops') should be handled for + /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT, + /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used. + /// + /// Note that these are laid out in a specific order to allow bit-twiddling + /// to transform conditions. + enum CondCode { + // Opcode N U L G E Intuitive operation + SETFALSE, // 0 0 0 0 Always false (always folded) + SETOEQ, // 0 0 0 1 True if ordered and equal + SETOGT, // 0 0 1 0 True if ordered and greater than + SETOGE, // 0 0 1 1 True if ordered and greater than or equal + SETOLT, // 0 1 0 0 True if ordered and less than + SETOLE, // 0 1 0 1 True if ordered and less than or equal + SETONE, // 0 1 1 0 True if ordered and operands are unequal + SETO, // 0 1 1 1 True if ordered (no nans) + SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y) + SETUEQ, // 1 0 0 1 True if unordered or equal + SETUGT, // 1 0 1 0 True if unordered or greater than + SETUGE, // 1 0 1 1 True if unordered, greater than, or equal + SETULT, // 1 1 0 0 True if unordered or less than + SETULE, // 1 1 0 1 True if unordered, less than, or equal + SETUNE, // 1 1 1 0 True if unordered or not equal + SETTRUE, // 1 1 1 1 Always true (always folded) + // Don't care operations: undefined if the input is a nan. + SETFALSE2, // 1 X 0 0 0 Always false (always folded) + SETEQ, // 1 X 0 0 1 True if equal + SETGT, // 1 X 0 1 0 True if greater than + SETGE, // 1 X 0 1 1 True if greater than or equal + SETLT, // 1 X 1 0 0 True if less than + SETLE, // 1 X 1 0 1 True if less than or equal + SETNE, // 1 X 1 1 0 True if not equal + SETTRUE2, // 1 X 1 1 1 Always true (always folded) + + SETCC_INVALID // Marker value. + }; + + /// isSignedIntSetCC - Return true if this is a setcc instruction that + /// performs a signed comparison when used with integer operands. + inline bool isSignedIntSetCC(CondCode Code) { + return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE; + } + + /// isUnsignedIntSetCC - Return true if this is a setcc instruction that + /// performs an unsigned comparison when used with integer operands. + inline bool isUnsignedIntSetCC(CondCode Code) { + return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE; + } + + /// isTrueWhenEqual - Return true if the specified condition returns true if + /// the two operands to the condition are equal. Note that if one of the two + /// operands is a NaN, this value is meaningless. + inline bool isTrueWhenEqual(CondCode Cond) { + return ((int)Cond & 1) != 0; + } + + /// getUnorderedFlavor - This function returns 0 if the condition is always + /// false if an operand is a NaN, 1 if the condition is always true if the + /// operand is a NaN, and 2 if the condition is undefined if the operand is a + /// NaN. + inline unsigned getUnorderedFlavor(CondCode Cond) { + return ((int)Cond >> 3) & 3; + } + + /// getSetCCInverse - Return the operation corresponding to !(X op Y), where + /// 'op' is a valid SetCC operation. + CondCode getSetCCInverse(CondCode Operation, bool isInteger); + + /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X) + /// when given the operation for (X op Y). + CondCode getSetCCSwappedOperands(CondCode Operation); + + /// getSetCCOrOperation - Return the result of a logical OR between different + /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This + /// function returns SETCC_INVALID if it is not possible to represent the + /// resultant comparison. + CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger); + + /// getSetCCAndOperation - Return the result of a logical AND between + /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This + /// function returns SETCC_INVALID if it is not possible to represent the + /// resultant comparison. + CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger); + + //===--------------------------------------------------------------------===// + /// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT + /// supports. + enum CvtCode { + CVT_FF, // Float from Float + CVT_FS, // Float from Signed + CVT_FU, // Float from Unsigned + CVT_SF, // Signed from Float + CVT_UF, // Unsigned from Float + CVT_SS, // Signed from Signed + CVT_SU, // Signed from Unsigned + CVT_US, // Unsigned from Signed + CVT_UU, // Unsigned from Unsigned + CVT_INVALID // Marker - Invalid opcode + }; + +} // end llvm::ISD namespace + +} // end llvm namespace + +#endif diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index 5da4961..eb373fb 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -21,6 +21,7 @@ #include "llvm/System/DataTypes.h" #include "llvm/Support/MathExtras.h" #include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/ADT/DenseMap.h" using namespace std; @@ -173,13 +174,20 @@ public: /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be /// written to the output stream. - void emitULEB128Bytes(uint64_t Value) { + void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) { do { uint8_t Byte = Value & 0x7f; Value >>= 7; - if (Value) Byte |= 0x80; + if (Value || PadTo != 0) Byte |= 0x80; emitByte(Byte); } while (Value); + + if (PadTo) { + do { + uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0; + emitByte(Byte); + } while (--PadTo); + } } /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be @@ -324,6 +332,10 @@ public: /// Specifies the MachineModuleInfo object. This is used for exception handling /// purposes. virtual void setModuleInfo(MachineModuleInfo* Info) = 0; + + /// getLabelLocations - Return the label locations map of the label IDs to + /// their address. + virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { return 0; } }; } // End llvm namespace diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 27947e8..0064776 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -34,6 +34,7 @@ namespace { (void) llvm::createDeadMachineInstructionElimPass(); (void) llvm::createLocalRegisterAllocator(); + (void) llvm::createFastRegisterAllocator(); (void) llvm::createLinearScanRegisterAllocator(); (void) llvm::createPBQPRegisterAllocator(); diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 8ddcac7..351217c 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -111,6 +111,12 @@ namespace llvm { double getScaledIntervalSize(LiveInterval& I) { return (1000.0 * I.getSize()) / indexes_->getIndexesLength(); } + + /// getFuncInstructionCount - Return the number of instructions in the + /// current function. + unsigned getFuncInstructionCount() { + return indexes_->getFunctionSize(); + } /// getApproximateInstructionCount - computes an estimate of the number /// of instructions in a given LiveInterval. diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 2995bea..cc651ca 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -201,12 +201,9 @@ public: // Iteration support for live in sets. These sets are kept in sorted // order by their register number. - typedef std::vector<unsigned>::iterator livein_iterator; - typedef std::vector<unsigned>::const_iterator const_livein_iterator; - livein_iterator livein_begin() { return LiveIns.begin(); } - const_livein_iterator livein_begin() const { return LiveIns.begin(); } - livein_iterator livein_end() { return LiveIns.end(); } - const_livein_iterator livein_end() const { return LiveIns.end(); } + typedef std::vector<unsigned>::const_iterator livein_iterator; + livein_iterator livein_begin() const { return LiveIns.begin(); } + livein_iterator livein_end() const { return LiveIns.end(); } bool livein_empty() const { return LiveIns.empty(); } /// getAlignment - Return alignment of the basic block. diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index e6698a5..498f815 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -74,7 +74,7 @@ class MachineConstantPoolEntry { public: /// The constant itself. union { - Constant *ConstVal; + const Constant *ConstVal; MachineConstantPoolValue *MachineCPVal; } Val; @@ -82,7 +82,7 @@ public: /// a MachineConstantPoolValue. unsigned Alignment; - MachineConstantPoolEntry(Constant *V, unsigned A) + MachineConstantPoolEntry(const Constant *V, unsigned A) : Alignment(A) { Val.ConstVal = V; } @@ -143,7 +143,7 @@ public: /// getConstantPoolIndex - Create a new entry in the constant pool or return /// an existing one. User must specify the minimum required alignment for /// the object. - unsigned getConstantPoolIndex(Constant *C, unsigned Alignment); + unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment); unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment); /// isEmpty - Return true if this constant pool contains no constants. diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index b3609c2..595872a 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -70,7 +70,7 @@ struct MachineFunctionInfo { }; class MachineFunction { - Function *Fn; + const Function *Fn; const TargetMachine &Target; MCContext &Ctx; MachineModuleInfo &MMI; @@ -109,10 +109,6 @@ class MachineFunction { typedef ilist<MachineBasicBlock> BasicBlockListType; BasicBlockListType BasicBlocks; - /// Default debug location. Used to print out the debug label at the beginning - /// of a function. - DebugLoc DefaultDebugLoc; - /// FunctionNumber - This provides a unique ID for each function emitted in /// this translation unit. /// @@ -124,8 +120,8 @@ class MachineFunction { MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT void operator=(const MachineFunction&); // DO NOT IMPLEMENT public: - MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum, - MachineModuleInfo &MMI); + MachineFunction(const Function *Fn, const TargetMachine &TM, + unsigned FunctionNum, MachineModuleInfo &MMI); ~MachineFunction(); MachineModuleInfo &getMMI() const { return MMI; } @@ -133,7 +129,7 @@ public: /// getFunction - Return the LLVM function that this machine code represents /// - Function *getFunction() const { return Fn; } + const Function *getFunction() const { return Fn; } /// getFunctionNumber - Return a unique ID for the current function. /// @@ -394,19 +390,6 @@ public: /// normal 'L' label is returned. MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, bool isLinkerPrivate = false) const; - - - //===--------------------------------------------------------------------===// - // Debug location. - // - - /// getDefaultDebugLoc - Get the default debug location for the machine - /// function. - DebugLoc getDefaultDebugLoc() const { return DefaultDebugLoc; } - - /// setDefaultDebugLoc - Get the default debug location for the machine - /// function. - void setDefaultDebugLoc(DebugLoc DL) { DefaultDebugLoc = DL; } }; //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index fa81927..c4adca1 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -91,15 +91,14 @@ private: // over time, the non-DebugLoc versions should be phased out and eventually // removed. - /// MachineInstr ctor - This constructor create a MachineInstr and add the - /// implicit operands. It reserves space for number of operands specified by - /// TargetInstrDesc. The version with a DebugLoc should be preferred. + /// MachineInstr ctor - This constructor creates a MachineInstr and adds the + /// implicit operands. It reserves space for the number of operands specified + /// by the TargetInstrDesc. The version with a DebugLoc should be preferred. explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic /// block. The version with a DebugLoc should be preferred. - /// MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); /// MachineInstr ctor - This constructor create a MachineInstr and add the @@ -111,7 +110,6 @@ private: /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic /// block. - /// MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const TargetInstrDesc &TID); @@ -357,6 +355,10 @@ public: /// return 0. unsigned isConstantValuePHI() const; + /// allDefsAreDead - Return true if all the defs of this instruction are dead. + /// + bool allDefsAreDead() const; + // // Debugging support // diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 9baa592..37ac24c 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -104,7 +104,7 @@ public: return *this; } - const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV, + const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV, int64_t Offset = 0, unsigned char TargetFlags = 0) const { MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags)); diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 17da43b..84aef10 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -82,7 +82,7 @@ struct LandingPadInfo { SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke. SmallVector<MCSymbol*, 1> EndLabels; // Labels after invoke. MCSymbol *LandingPadLabel; // Label at beginning of landing pad. - Function *Personality; // Personality function. + const Function *Personality; // Personality function. std::vector<int> TypeIds; // List of type ids (filters negative) explicit LandingPadInfo(MachineBasicBlock *MBB) @@ -101,7 +101,7 @@ class MachineModuleInfo : public ImmutablePass { MCContext Context; /// TheModule - This is the LLVM Module being worked on. - Module *TheModule; + const Module *TheModule; /// ObjFileMMI - This is the object-file-format-specific implementation of /// MachineModuleInfoImpl, which lets targets accumulate whatever info they @@ -125,7 +125,7 @@ class MachineModuleInfo : public ImmutablePass { // TypeInfos - List of C++ TypeInfo used in the current function. // - std::vector<GlobalVariable *> TypeInfos; + std::vector<const GlobalVariable *> TypeInfos; // FilterIds - List of typeids encoding filters used in the current function. // @@ -138,7 +138,7 @@ class MachineModuleInfo : public ImmutablePass { // Personalities - Vector of all personality functions ever seen. Used to emit // common EH frames. - std::vector<Function *> Personalities; + std::vector<const Function *> Personalities; /// UsedFunctions - The functions in the @llvm.used list in a more easily /// searchable format. This does not include the functions in @@ -179,8 +179,8 @@ public: const MCContext &getContext() const { return Context; } MCContext &getContext() { return Context; } - void setModule(Module *M) { TheModule = M; } - Module *getModule() const { return TheModule; } + void setModule(const Module *M) { TheModule = M; } + const Module *getModule() const { return TheModule; } /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. @@ -199,7 +199,7 @@ public: /// AnalyzeModule - Scan the module for global debug information. /// - void AnalyzeModule(Module &M); + void AnalyzeModule(const Module &M); /// hasDebugInfo - Returns true if valid debug info is present. /// @@ -252,14 +252,15 @@ public: /// addPersonality - Provide the personality function for the exception /// information. - void addPersonality(MachineBasicBlock *LandingPad, Function *Personality); + void addPersonality(MachineBasicBlock *LandingPad, + const Function *Personality); /// getPersonalityIndex - Get index of the current personality function inside /// Personalitites array unsigned getPersonalityIndex() const; /// getPersonalities - Return array of personality functions ever seen. - const std::vector<Function *>& getPersonalities() const { + const std::vector<const Function *>& getPersonalities() const { return Personalities; } @@ -273,12 +274,12 @@ public: /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// void addCatchTypeInfo(MachineBasicBlock *LandingPad, - std::vector<GlobalVariable *> &TyInfo); + std::vector<const GlobalVariable *> &TyInfo); /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// void addFilterTypeInfo(MachineBasicBlock *LandingPad, - std::vector<GlobalVariable *> &TyInfo); + std::vector<const GlobalVariable *> &TyInfo); /// addCleanup - Add a cleanup action for a landing pad. /// @@ -286,7 +287,7 @@ public: /// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. - unsigned getTypeIDFor(GlobalVariable *TI); + unsigned getTypeIDFor(const GlobalVariable *TI); /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is /// function wide. @@ -294,7 +295,7 @@ public: /// TidyLandingPads - Remap landing pad labels and remove any deleted landing /// pads. - void TidyLandingPads(); + void TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = 0); /// getLandingPads - Return a reference to the landing pad info for the /// current function. @@ -323,7 +324,7 @@ public: /// getTypeInfos - Return a reference to the C++ typeinfo for the current /// function. - const std::vector<GlobalVariable *> &getTypeInfos() const { + const std::vector<const GlobalVariable *> &getTypeInfos() const { return TypeInfos; } @@ -335,7 +336,7 @@ public: /// getPersonality - Return a personality function if available. The presence /// of one is required to emit exception handling info. - Function *getPersonality() const; + const Function *getPersonality() const; /// setVariableDbgInfo - Collect information used to emit debugging /// information of a variable. diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index b5f6bcd..31858ce 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -117,8 +117,8 @@ private: union { int Index; // For MO_*Index - The index itself. const char *SymbolName; // For MO_ExternalSymbol. - GlobalValue *GV; // For MO_GlobalAddress. - BlockAddress *BA; // For MO_BlockAddress. + const GlobalValue *GV; // For MO_GlobalAddress. + const BlockAddress *BA; // For MO_BlockAddress. } Val; int64_t Offset; // An offset from the object. } OffsetedInfo; @@ -315,12 +315,12 @@ public: return Contents.OffsetedInfo.Val.Index; } - GlobalValue *getGlobal() const { + const GlobalValue *getGlobal() const { assert(isGlobal() && "Wrong MachineOperand accessor"); return Contents.OffsetedInfo.Val.GV; } - BlockAddress *getBlockAddress() const { + const BlockAddress *getBlockAddress() const { assert(isBlockAddress() && "Wrong MachineOperand accessor"); return Contents.OffsetedInfo.Val.BA; } @@ -457,7 +457,7 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset, + static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_GlobalAddress); Op.Contents.OffsetedInfo.Val.GV = GV; @@ -473,7 +473,7 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateBA(BlockAddress *BA, + static MachineOperand CreateBA(const BlockAddress *BA, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_BlockAddress); Op.Contents.OffsetedInfo.Val.BA = BA; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index f2e5e10..b377dec 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -258,18 +258,18 @@ public: liveout_iterator liveout_end() const { return LiveOuts.end(); } bool liveout_empty() const { return LiveOuts.empty(); } - bool isLiveIn(unsigned Reg) const { - for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) - if (I->first == Reg || I->second == Reg) - return true; - return false; - } - bool isLiveOut(unsigned Reg) const { - for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) - if (*I == Reg) - return true; - return false; - } + bool isLiveIn(unsigned Reg) const; + bool isLiveOut(unsigned Reg) const; + + /// getLiveInPhysReg - If VReg is a live-in virtual register, return the + /// corresponding live-in physical register. + unsigned getLiveInPhysReg(unsigned VReg) const; + + /// EmitLiveInCopies - Emit copies to initialize livein virtual registers + /// into the given entry block. + void EmitLiveInCopies(MachineBasicBlock *EntryMBB, + const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII); private: void HandleVRegListReallocation(); diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h index ab663fe..979ef01 100644 --- a/include/llvm/CodeGen/MachineSSAUpdater.h +++ b/include/llvm/CodeGen/MachineSSAUpdater.h @@ -23,22 +23,27 @@ namespace llvm { class TargetInstrInfo; class TargetRegisterClass; template<typename T> class SmallVectorImpl; + class BumpPtrAllocator; /// MachineSSAUpdater - This class updates SSA form for a set of virtual /// registers defined in multiple blocks. This is used when code duplication /// or another unstructured transformation wants to rewrite a set of uses of one /// vreg with uses of a set of vregs. class MachineSSAUpdater { +public: + class BBInfo; + typedef SmallVectorImpl<BBInfo*> BlockListTy; + +private: /// AvailableVals - This keeps track of which value to use on a per-block /// basis. When we insert PHI nodes, we keep track of them here. //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy; void *AV; - /// IncomingPredInfo - We use this as scratch space when doing our recursive - /// walk. This should only be used in GetValueInBlockInternal, normally it - /// should be empty. - //std::vector<std::pair<MachineBasicBlock*, unsigned > > IncomingPredInfo; - void *IPI; + /// BBMap - The GetValueAtEndOfBlock method maintains this mapping from + /// basic blocks to BBInfo structures. + /// typedef DenseMap<MachineBasicBlock*, BBInfo*> BBMapTy; + void *BM; /// VR - Current virtual register whose uses are being updated. unsigned VR; @@ -106,6 +111,15 @@ public: private: void ReplaceRegWith(unsigned OldReg, unsigned NewReg); unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB); + void BuildBlockList(MachineBasicBlock *BB, BlockListTy *BlockList, + BumpPtrAllocator *Allocator); + void FindDominators(BlockListTy *BlockList); + void FindPHIPlacement(BlockListTy *BlockList); + void FindAvailableVals(BlockListTy *BlockList); + void FindExistingPHI(MachineBasicBlock *BB, BlockListTy *BlockList); + bool CheckIfPHIMatches(MachineInstr *PHI); + void RecordMatchingPHI(MachineInstr *PHI); + void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT }; diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index d3c2720..2f5d576 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -95,6 +95,11 @@ namespace llvm { /// FunctionPass *createLocalRegisterAllocator(); + /// FastRegisterAllocation Pass - This pass register allocates as fast as + /// possible. It is best suited for debug code where live ranges are short. + /// + FunctionPass *createFastRegisterAllocator(); + /// LinearScanRegisterAllocation Pass - This pass implements the linear scan /// register allocation algorithm, a global register allocator. /// @@ -170,7 +175,7 @@ namespace llvm { /// createMachineLICMPass - This pass performs LICM on machine instructions. /// - FunctionPass *createMachineLICMPass(); + FunctionPass *createMachineLICMPass(bool PreRegAlloc = true); /// createMachineSinkingPass - This pass performs sinking on machine /// instructions. @@ -199,7 +204,7 @@ namespace llvm { /// createDwarfEHPass - This pass mulches exception handling code into a form /// adapted to code generation. Required if using dwarf exception handling. - FunctionPass *createDwarfEHPass(const TargetLowering *tli, bool fast); + FunctionPass *createDwarfEHPass(const TargetMachine *tm, bool fast); /// createSjLjEHPass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 9563d08..7c025e3 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -459,7 +459,6 @@ namespace llvm { const TargetLowering *TLI; // Target lowering info MachineFunction &MF; // Machine function MachineRegisterInfo &MRI; // Virtual/real register map - MachineConstantPool *ConstPool; // Target constant pool std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s // represent noop instructions. std::vector<SUnit> SUnits; // The scheduling units. @@ -478,8 +477,7 @@ namespace llvm { /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock /// according to the order specified in Sequence. /// - virtual MachineBasicBlock* - EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*>*) = 0; + virtual MachineBasicBlock *EmitSchedule() = 0; void dumpSchedule() const; diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 5dd0aa8..ae15230 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -62,8 +62,15 @@ private: /// instead the info is kept off to the side in this structure. Each SDNode may /// have one or more associated dbg_value entries. This information is kept in /// DbgValMap. +/// Byval parameters are handled separately because they don't use alloca's, +/// which busts the normal mechanism. There is good reason for handling all +/// parameters separately: they may not have code generated for them, they +/// should always go at the beginning of the function regardless of other code +/// motion, and debug info for them is potentially useful even if the parameter +/// is unused. Right now only byval parameters are handled separately. class SDDbgInfo { SmallVector<SDDbgValue*, 32> DbgValues; + SmallVector<SDDbgValue*, 32> ByvalParmDbgValues; DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap; void operator=(const SDDbgInfo&); // Do not implement. @@ -71,19 +78,22 @@ class SDDbgInfo { public: SDDbgInfo() {} - void add(SDDbgValue *V, const SDNode *Node = 0) { + void add(SDDbgValue *V, const SDNode *Node, bool isParameter) { + if (isParameter) { + ByvalParmDbgValues.push_back(V); + } else DbgValues.push_back(V); if (Node) DbgValMap[Node].push_back(V); - DbgValues.push_back(V); } void clear() { DbgValMap.clear(); DbgValues.clear(); + ByvalParmDbgValues.clear(); } bool empty() const { - return DbgValues.empty(); + return DbgValues.empty() && ByvalParmDbgValues.empty(); } SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) { @@ -93,6 +103,8 @@ public: typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator; DbgIterator DbgBegin() { return DbgValues.begin(); } DbgIterator DbgEnd() { return DbgValues.end(); } + DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); } + DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); } }; enum CombineLevel { @@ -117,7 +129,8 @@ void checkForCycles(const SelectionDAG *DAG); /// linear form. /// class SelectionDAG { - TargetLowering &TLI; + const TargetMachine &TM; + const TargetLowering &TLI; MachineFunction *MF; FunctionLoweringInfo &FLI; LLVMContext *Context; @@ -172,7 +185,7 @@ class SelectionDAG { SelectionDAG(const SelectionDAG&); // Do not implement. public: - SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli); + SelectionDAG(const TargetMachine &TM, FunctionLoweringInfo &fli); ~SelectionDAG(); /// init - Prepare this SelectionDAG to process code in the given @@ -186,8 +199,8 @@ public: void clear(); MachineFunction &getMachineFunction() const { return *MF; } - const TargetMachine &getTarget() const; - TargetLowering &getTargetLoweringInfo() const { return TLI; } + const TargetMachine &getTarget() const { return TM; } + const TargetLowering &getTargetLoweringInfo() const { return TLI; } FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } LLVMContext *getContext() const {return Context; } @@ -350,10 +363,10 @@ public: SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags = 0) { return getJumpTable(JTI, VT, true, TargetFlags); } - SDValue getConstantPool(Constant *C, EVT VT, + SDValue getConstantPool(const Constant *C, EVT VT, unsigned Align = 0, int Offs = 0, bool isT=false, unsigned char TargetFlags = 0); - SDValue getTargetConstantPool(Constant *C, EVT VT, + SDValue getTargetConstantPool(const Constant *C, EVT VT, unsigned Align = 0, int Offset = 0, unsigned char TargetFlags = 0) { return getConstantPool(C, VT, Align, Offset, true, TargetFlags); @@ -377,7 +390,7 @@ public: SDValue getValueType(EVT); SDValue getRegister(unsigned Reg, EVT VT); SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label); - SDValue getBlockAddress(BlockAddress *BA, EVT VT, + SDValue getBlockAddress(const BlockAddress *BA, EVT VT, bool isTarget = false, unsigned char TargetFlags = 0); SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) { @@ -650,6 +663,9 @@ public: /// getSrcValue - Construct a node to track a Value* through the backend. SDValue getSrcValue(const Value *v); + /// getMDNode - Return an MDNodeSDNode which holds an MDNode. + SDValue getMDNode(const MDNode *MD); + /// getShiftAmountOperand - Return the specified value casted to /// the target's desired shift amount type. SDValue getShiftAmountOperand(SDValue Op); @@ -764,7 +780,7 @@ public: /// SDDbgValue *getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, uint64_t Off, DebugLoc DL, unsigned O); - SDDbgValue *getDbgValue(MDNode *MDPtr, Value *C, uint64_t Off, + SDDbgValue *getDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off, DebugLoc DL, unsigned O); SDDbgValue *getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, DebugLoc DL, unsigned O); @@ -873,7 +889,7 @@ public: /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the /// value is produced by SD. - void AddDbgValue(SDDbgValue *DB, SDNode *SD = 0); + void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); /// GetDbgValues - Get the debug values which reference the given SDNode. SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { @@ -886,6 +902,12 @@ public: SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); } SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); } + SDDbgInfo::DbgIterator ByvalParmDbgBegin() { + return DbgInfo->ByvalParmDbgBegin(); + } + SDDbgInfo::DbgIterator ByvalParmDbgEnd() { + return DbgInfo->ByvalParmDbgEnd(); + } void dump() const; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 3c000f0..3817580 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -17,7 +17,6 @@ #include "llvm/BasicBlock.h" #include "llvm/Pass.h" -#include "llvm/Constant.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -41,31 +40,28 @@ namespace llvm { class SelectionDAGISel : public MachineFunctionPass { public: const TargetMachine &TM; - TargetLowering &TLI; + const TargetLowering &TLI; FunctionLoweringInfo *FuncInfo; MachineFunction *MF; MachineRegisterInfo *RegInfo; SelectionDAG *CurDAG; SelectionDAGBuilder *SDB; - MachineBasicBlock *BB; AliasAnalysis *AA; GCFunctionInfo *GFI; CodeGenOpt::Level OptLevel; static char ID; - explicit SelectionDAGISel(TargetMachine &tm, + explicit SelectionDAGISel(const TargetMachine &tm, CodeGenOpt::Level OL = CodeGenOpt::Default); virtual ~SelectionDAGISel(); - TargetLowering &getTargetLowering() { return TLI; } + const TargetLowering &getTargetLowering() { return TLI; } virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnMachineFunction(MachineFunction &MF); - unsigned MakeReg(EVT VT); - - virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {} + virtual void EmitFunctionEntryCode() {} /// PreprocessISelDAG - This hook allows targets to hack on the graph before /// instruction selection starts. @@ -95,8 +91,11 @@ public: /// IsLegalToFold - Returns true if the specific operand node N of /// U can be folded during instruction selection that starts at Root. - bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, - bool IgnoreChains = false) const; + /// FIXME: This is a static member function because the PIC16 target, + /// which uses it during lowering. + static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, + CodeGenOpt::Level OptLevel, + bool IgnoreChains = false); /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. @@ -281,24 +280,21 @@ private: SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); - void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, - const TargetInstrInfo &TII); - void FinishBasicBlock(); + void PrepareEHLandingPad(MachineBasicBlock *BB); + void SelectAllBasicBlocks(const Function &Fn); + void FinishBasicBlock(MachineBasicBlock *BB); - void SelectBasicBlock(BasicBlock *LLVMBB, - BasicBlock::iterator Begin, - BasicBlock::iterator End, - bool &HadTailCall); - void CodeGenAndEmitDAG(); - void LowerArguments(BasicBlock *BB); + MachineBasicBlock *SelectBasicBlock(MachineBasicBlock *BB, + const BasicBlock *LLVMBB, + BasicBlock::const_iterator Begin, + BasicBlock::const_iterator End, + bool &HadTailCall); + MachineBasicBlock *CodeGenAndEmitDAG(MachineBasicBlock *BB); + void LowerArguments(const BasicBlock *BB); void ShrinkDemandedOps(); void ComputeLiveOutVRegInfo(); - void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB); - - bool HandlePHINodesInSuccessorBlocksFast(BasicBlock *LLVMBB, FastISel *F); - /// Create the scheduler. If a specific scheduler was specified /// via the SchedulerRegistry, use it, otherwise select the /// one preferred by the target. diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 782d354..fd529b6 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -25,6 +25,7 @@ #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/Support/MathExtras.h" @@ -56,568 +57,7 @@ struct SDVTList { unsigned int NumVTs; }; -/// ISD namespace - This namespace contains an enum which represents all of the -/// SelectionDAG node types and value types. -/// namespace ISD { - - //===--------------------------------------------------------------------===// - /// ISD::NodeType enum - This enum defines the target-independent operators - /// for a SelectionDAG. - /// - /// Targets may also define target-dependent operator codes for SDNodes. For - /// example, on x86, these are the enum values in the X86ISD namespace. - /// Targets should aim to use target-independent operators to model their - /// instruction sets as much as possible, and only use target-dependent - /// operators when they have special requirements. - /// - /// Finally, during and after selection proper, SNodes may use special - /// operator codes that correspond directly with MachineInstr opcodes. These - /// are used to represent selected instructions. See the isMachineOpcode() - /// and getMachineOpcode() member functions of SDNode. - /// - enum NodeType { - // DELETED_NODE - This is an illegal value that is used to catch - // errors. This opcode is not a legal opcode for any node. - DELETED_NODE, - - // EntryToken - This is the marker used to indicate the start of the region. - EntryToken, - - // TokenFactor - This node takes multiple tokens as input and produces a - // single token result. This is used to represent the fact that the operand - // operators are independent of each other. - TokenFactor, - - // AssertSext, AssertZext - These nodes record if a register contains a - // value that has already been zero or sign extended from a narrower type. - // These nodes take two operands. The first is the node that has already - // been extended, and the second is a value type node indicating the width - // of the extension - AssertSext, AssertZext, - - // Various leaf nodes. - BasicBlock, VALUETYPE, CONDCODE, Register, - Constant, ConstantFP, - GlobalAddress, GlobalTLSAddress, FrameIndex, - JumpTable, ConstantPool, ExternalSymbol, BlockAddress, - - // The address of the GOT - GLOBAL_OFFSET_TABLE, - - // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and - // llvm.returnaddress on the DAG. These nodes take one operand, the index - // of the frame or return address to return. An index of zero corresponds - // to the current function's frame or return address, an index of one to the - // parent's frame or return address, and so on. - FRAMEADDR, RETURNADDR, - - // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to - // first (possible) on-stack argument. This is needed for correct stack - // adjustment during unwind. - FRAME_TO_ARGS_OFFSET, - - // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the - // address of the exception block on entry to an landing pad block. - EXCEPTIONADDR, - - // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the - // address of the Language Specific Data Area for the enclosing function. - LSDAADDR, - - // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents - // the selection index of the exception thrown. - EHSELECTION, - - // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents - // 'eh_return' gcc dwarf builtin, which is used to return from - // exception. The general meaning is: adjust stack by OFFSET and pass - // execution to HANDLER. Many platform-related details also :) - EH_RETURN, - - // TargetConstant* - Like Constant*, but the DAG does not do any folding or - // simplification of the constant. - TargetConstant, - TargetConstantFP, - - // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or - // anything else with this node, and this is valid in the target-specific - // dag, turning into a GlobalAddress operand. - TargetGlobalAddress, - TargetGlobalTLSAddress, - TargetFrameIndex, - TargetJumpTable, - TargetConstantPool, - TargetExternalSymbol, - TargetBlockAddress, - - /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) - /// This node represents a target intrinsic function with no side effects. - /// The first operand is the ID number of the intrinsic from the - /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The - /// node has returns the result of the intrinsic. - INTRINSIC_WO_CHAIN, - - /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) - /// This node represents a target intrinsic function with side effects that - /// returns a result. The first operand is a chain pointer. The second is - /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The - /// operands to the intrinsic follow. The node has two results, the result - /// of the intrinsic and an output chain. - INTRINSIC_W_CHAIN, - - /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) - /// This node represents a target intrinsic function with side effects that - /// does not return a result. The first operand is a chain pointer. The - /// second is the ID number of the intrinsic from the llvm::Intrinsic - /// namespace. The operands to the intrinsic follow. - INTRINSIC_VOID, - - // CopyToReg - This node has three operands: a chain, a register number to - // set to this value, and a value. - CopyToReg, - - // CopyFromReg - This node indicates that the input value is a virtual or - // physical register that is defined outside of the scope of this - // SelectionDAG. The register is available from the RegisterSDNode object. - CopyFromReg, - - // UNDEF - An undefined node - UNDEF, - - // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by - // a Constant, which is required to be operand #1) half of the integer or - // float value specified as operand #0. This is only for use before - // legalization, for values that will be broken into multiple registers. - EXTRACT_ELEMENT, - - // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given - // two values of the same integer value type, this produces a value twice as - // big. Like EXTRACT_ELEMENT, this can only be used before legalization. - BUILD_PAIR, - - // MERGE_VALUES - This node takes multiple discrete operands and returns - // them all as its individual results. This nodes has exactly the same - // number of inputs and outputs. This node is useful for some pieces of the - // code generator that want to think about a single node with multiple - // results, not multiple nodes. - MERGE_VALUES, - - // Simple integer binary arithmetic operators. - ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, - - // SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing - // a signed/unsigned value of type i[2*N], and return the full value as - // two results, each of type iN. - SMUL_LOHI, UMUL_LOHI, - - // SDIVREM/UDIVREM - Divide two integers and produce both a quotient and - // remainder result. - SDIVREM, UDIVREM, - - // CARRY_FALSE - This node is used when folding other nodes, - // like ADDC/SUBC, which indicate the carry result is always false. - CARRY_FALSE, - - // Carry-setting nodes for multiple precision addition and subtraction. - // These nodes take two operands of the same value type, and produce two - // results. The first result is the normal add or sub result, the second - // result is the carry flag result. - ADDC, SUBC, - - // Carry-using nodes for multiple precision addition and subtraction. These - // nodes take three operands: The first two are the normal lhs and rhs to - // the add or sub, and the third is the input carry flag. These nodes - // produce two results; the normal result of the add or sub, and the output - // carry flag. These nodes both read and write a carry flag to allow them - // to them to be chained together for add and sub of arbitrarily large - // values. - ADDE, SUBE, - - // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. - // These nodes take two operands: the normal LHS and RHS to the add. They - // produce two results: the normal result of the add, and a boolean that - // indicates if an overflow occured (*not* a flag, because it may be stored - // to memory, etc.). If the type of the boolean is not i1 then the high - // bits conform to getBooleanContents. - // These nodes are generated from the llvm.[su]add.with.overflow intrinsics. - SADDO, UADDO, - - // Same for subtraction - SSUBO, USUBO, - - // Same for multiplication - SMULO, UMULO, - - // Simple binary floating point operators. - FADD, FSUB, FMUL, FDIV, FREM, - - // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This - // DAG node does not require that X and Y have the same type, just that they - // are both floating point. X and the result must have the same type. - // FCOPYSIGN(f32, f64) is allowed. - FCOPYSIGN, - - // INT = FGETSIGN(FP) - Return the sign bit of the specified floating point - // value as an integer 0/1 value. - FGETSIGN, - - /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the - /// specified, possibly variable, elements. The number of elements is - /// required to be a power of two. The types of the operands must all be - /// the same and must match the vector element type, except that integer - /// types are allowed to be larger than the element type, in which case - /// the operands are implicitly truncated. - BUILD_VECTOR, - - /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element - /// at IDX replaced with VAL. If the type of VAL is larger than the vector - /// element type then VAL is truncated before replacement. - INSERT_VECTOR_ELT, - - /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR - /// identified by the (potentially variable) element number IDX. If the - /// return type is an integer type larger than the element type of the - /// vector, the result is extended to the width of the return type. - EXTRACT_VECTOR_ELT, - - /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of - /// vector type with the same length and element type, this produces a - /// concatenated vector result value, with length equal to the sum of the - /// lengths of the input vectors. - CONCAT_VECTORS, - - /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an - /// vector value) starting with the (potentially variable) element number - /// IDX, which must be a multiple of the result vector length. - EXTRACT_SUBVECTOR, - - /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as - /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int - /// values that indicate which value (or undef) each result element will - /// get. These constant ints are accessible through the - /// ShuffleVectorSDNode class. This is quite similar to the Altivec - /// 'vperm' instruction, except that the indices must be constants and are - /// in terms of the element size of VEC1/VEC2, not in terms of bytes. - VECTOR_SHUFFLE, - - /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a - /// scalar value into element 0 of the resultant vector type. The top - /// elements 1 to N-1 of the N-element vector are undefined. The type - /// of the operand must match the vector element type, except when they - /// are integer types. In this case the operand is allowed to be wider - /// than the vector element type, and is implicitly truncated to it. - SCALAR_TO_VECTOR, - - // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing - // an unsigned/signed value of type i[2*N], then return the top part. - MULHU, MULHS, - - // Bitwise operators - logical and, logical or, logical xor, shift left, - // shift right algebraic (shift in sign bits), shift right logical (shift in - // zeroes), rotate left, rotate right, and byteswap. - AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP, - - // Counting operators - CTTZ, CTLZ, CTPOP, - - // Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not - // i1 then the high bits must conform to getBooleanContents. - SELECT, - - // Select with condition operator - This selects between a true value and - // a false value (ops #2 and #3) based on the boolean result of comparing - // the lhs and rhs (ops #0 and #1) of a conditional expression with the - // condition code in op #4, a CondCodeSDNode. - SELECT_CC, - - // SetCC operator - This evaluates to a true value iff the condition is - // true. If the result value type is not i1 then the high bits conform - // to getBooleanContents. The operands to this are the left and right - // operands to compare (ops #0, and #1) and the condition code to compare - // them with (op #2) as a CondCodeSDNode. - SETCC, - - // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of - // integer elements with all bits of the result elements set to true if the - // comparison is true or all cleared if the comparison is false. The - // operands to this are the left and right operands to compare (LHS/RHS) and - // the condition code to compare them with (COND) as a CondCodeSDNode. - VSETCC, - - // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded - // integer shift operations, just like ADD/SUB_PARTS. The operation - // ordering is: - // [Lo,Hi] = op [LoLHS,HiLHS], Amt - SHL_PARTS, SRA_PARTS, SRL_PARTS, - - // Conversion operators. These are all single input single output - // operations. For all of these, the result type must be strictly - // wider or narrower (depending on the operation) than the source - // type. - - // SIGN_EXTEND - Used for integer types, replicating the sign bit - // into new bits. - SIGN_EXTEND, - - // ZERO_EXTEND - Used for integer types, zeroing the new bits. - ZERO_EXTEND, - - // ANY_EXTEND - Used for integer types. The high bits are undefined. - ANY_EXTEND, - - // TRUNCATE - Completely drop the high bits. - TRUNCATE, - - // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign - // depends on the first letter) to floating point. - SINT_TO_FP, - UINT_TO_FP, - - // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to - // sign extend a small value in a large integer register (e.g. sign - // extending the low 8 bits of a 32-bit register to fill the top 24 bits - // with the 7th bit). The size of the smaller type is indicated by the 1th - // operand, a ValueType node. - SIGN_EXTEND_INREG, - - /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned - /// integer. - FP_TO_SINT, - FP_TO_UINT, - - /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type - /// down to the precision of the destination VT. TRUNC is a flag, which is - /// always an integer that is zero or one. If TRUNC is 0, this is a - /// normal rounding, if it is 1, this FP_ROUND is known to not change the - /// value of Y. - /// - /// The TRUNC = 1 case is used in cases where we know that the value will - /// not be modified by the node, because Y is not using any of the extra - /// precision of source type. This allows certain transformations like - /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for - /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed. - FP_ROUND, - - // FLT_ROUNDS_ - Returns current rounding mode: - // -1 Undefined - // 0 Round to 0 - // 1 Round to nearest - // 2 Round to +inf - // 3 Round to -inf - FLT_ROUNDS_, - - /// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and - /// rounds it to a floating point value. It then promotes it and returns it - /// in a register of the same size. This operation effectively just - /// discards excess precision. The type to round down to is specified by - /// the VT operand, a VTSDNode. - FP_ROUND_INREG, - - /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type. - FP_EXTEND, - - // 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 - // between various types (float, signed, unsigned and vectors of those - // types) with rounding and saturation. NOTE: Avoid using this operator as - // most target don't support it and the operator might be removed in the - // future. It takes the following arguments: - // 0) value - // 1) dest type (type to convert to) - // 2) src type (type to convert from) - // 3) rounding imm - // 4) saturation imm - // 5) ISD::CvtCode indicating the type of conversion to do - CONVERT_RNDSAT, - - // FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform - // promotions and truncation for half-precision (16 bit) floating - // numbers. We need special nodes since FP16 is a storage-only type with - // special semantics of operations. - FP16_TO_FP32, FP32_TO_FP16, - - // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, - // FLOG, FLOG2, FLOG10, FEXP, FEXP2, - // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating - // point operations. These are inspired by libm. - FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, - FLOG, FLOG2, FLOG10, FEXP, FEXP2, - FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR, - - // LOAD and STORE have token chains as their first operand, then the same - // operands as an LLVM load/store instruction, then an offset node that - // is added / subtracted from the base pointer to form the address (for - // indexed memory ops). - LOAD, STORE, - - // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned - // to a specified boundary. This node always has two return values: a new - // stack pointer value and a chain. The first operand is the token chain, - // the second is the number of bytes to allocate, and the third is the - // alignment boundary. The size is guaranteed to be a multiple of the stack - // alignment, and the alignment is guaranteed to be bigger than the stack - // alignment (if required) or 0 to get standard stack alignment. - DYNAMIC_STACKALLOC, - - // Control flow instructions. These all have token chains. - - // BR - Unconditional branch. The first operand is the chain - // operand, the second is the MBB to branch to. - BR, - - // BRIND - Indirect branch. The first operand is the chain, the second - // is the value to branch to, which must be of the same type as the target's - // pointer type. - BRIND, - - // BR_JT - Jumptable branch. The first operand is the chain, the second - // is the jumptable index, the last one is the jumptable entry index. - BR_JT, - - // BRCOND - Conditional branch. The first operand is the chain, the - // second is the condition, the third is the block to branch to if the - // condition is true. If the type of the condition is not i1, then the - // high bits must conform to getBooleanContents. - BRCOND, - - // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in - // that the condition is represented as condition code, and two nodes to - // compare, rather than as a combined SetCC node. The operands in order are - // chain, cc, lhs, rhs, block to branch to if condition is true. - BR_CC, - - // INLINEASM - Represents an inline asm block. This node always has two - // return values: a chain and a flag result. The inputs are as follows: - // Operand #0 : Input chain. - // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string. - // Operand #2n+2: A RegisterNode. - // Operand #2n+3: A TargetConstant, indicating if the reg is a use/def - // Operand #last: Optional, an incoming flag. - INLINEASM, - - // EH_LABEL - Represents a label in mid basic block used to track - // locations needed for debug and exception handling tables. These nodes - // take a chain as input and return a chain. - EH_LABEL, - - // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a - // value, the same type as the pointer type for the system, and an output - // chain. - STACKSAVE, - - // STACKRESTORE has two operands, an input chain and a pointer to restore to - // it returns an output chain. - STACKRESTORE, - - // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of - // a call sequence, and carry arbitrary information that target might want - // to know. The first operand is a chain, the rest are specified by the - // target and not touched by the DAG optimizers. - // CALLSEQ_START..CALLSEQ_END pairs may not be nested. - CALLSEQ_START, // Beginning of a call sequence - CALLSEQ_END, // End of a call sequence - - // VAARG - VAARG has three operands: an input chain, a pointer, and a - // SRCVALUE. It returns a pair of values: the vaarg value and a new chain. - VAARG, - - // VACOPY - VACOPY has five operands: an input chain, a destination pointer, - // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the - // source. - VACOPY, - - // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a - // pointer, and a SRCVALUE. - VAEND, VASTART, - - // SRCVALUE - This is a node type that holds a Value* that is used to - // make reference to a value in the LLVM IR. - SRCVALUE, - - // PCMARKER - This corresponds to the pcmarker intrinsic. - PCMARKER, - - // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic. - // The only operand is a chain and a value and a chain are produced. The - // value is the contents of the architecture specific cycle counter like - // register (or other high accuracy low latency clock source) - READCYCLECOUNTER, - - // HANDLENODE node - Used as a handle for various purposes. - HANDLENODE, - - // TRAMPOLINE - This corresponds to the init_trampoline intrinsic. - // It takes as input a token chain, the pointer to the trampoline, - // the pointer to the nested function, the pointer to pass for the - // 'nest' parameter, a SRCVALUE for the trampoline and another for - // the nested function (allowing targets to access the original - // Function*). It produces the result of the intrinsic and a token - // chain as output. - TRAMPOLINE, - - // TRAP - Trapping instruction - TRAP, - - // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are - // their first operand. The other operands are the address to prefetch, - // read / write specifier, and locality specifier. - PREFETCH, - - // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, - // store-store, device) - // This corresponds to the memory.barrier intrinsic. - // it takes an input chain, 4 operands to specify the type of barrier, an - // operand specifying if the barrier applies to device and uncached memory - // and produces an output chain. - MEMBARRIER, - - // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) - // this corresponds to the atomic.lcs intrinsic. - // cmp is compared to *ptr, and if equal, swap is stored in *ptr. - // the return is always the original value in *ptr - ATOMIC_CMP_SWAP, - - // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) - // this corresponds to the atomic.swap intrinsic. - // amt is stored to *ptr atomically. - // the return is always the original value in *ptr - ATOMIC_SWAP, - - // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) - // this corresponds to the atomic.load.[OpName] intrinsic. - // op(*ptr, amt) is stored to *ptr atomically. - // the return is always the original value in *ptr - ATOMIC_LOAD_ADD, - ATOMIC_LOAD_SUB, - ATOMIC_LOAD_AND, - ATOMIC_LOAD_OR, - ATOMIC_LOAD_XOR, - ATOMIC_LOAD_NAND, - ATOMIC_LOAD_MIN, - ATOMIC_LOAD_MAX, - ATOMIC_LOAD_UMIN, - ATOMIC_LOAD_UMAX, - - /// BUILTIN_OP_END - This must be the last enum value in this list. - /// The target-specific pre-isel opcode values start here. - BUILTIN_OP_END - }; - - /// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations - /// which do not reference a specific memory location should be less than - /// this value. Those that do must not be less than this value, and can - /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100; - /// Node predicates /// isBuildVectorAllOnes - Return true if the specified node is a @@ -632,174 +72,7 @@ namespace ISD { /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low /// element is not an undef. bool isScalarToVector(const SDNode *N); - - //===--------------------------------------------------------------------===// - /// MemIndexedMode enum - This enum defines the load / store indexed - /// addressing modes. - /// - /// UNINDEXED "Normal" load / store. The effective address is already - /// computed and is available in the base pointer. The offset - /// operand is always undefined. In addition to producing a - /// chain, an unindexed load produces one value (result of the - /// load); an unindexed store does not produce a value. - /// - /// PRE_INC Similar to the unindexed mode where the effective address is - /// PRE_DEC the value of the base pointer add / subtract the offset. - /// It considers the computation as being folded into the load / - /// store operation (i.e. the load / store does the address - /// computation as well as performing the memory transaction). - /// The base operand is always undefined. In addition to - /// producing a chain, pre-indexed load produces two values - /// (result of the load and the result of the address - /// computation); a pre-indexed store produces one value (result - /// of the address computation). - /// - /// POST_INC The effective address is the value of the base pointer. The - /// POST_DEC value of the offset operand is then added to / subtracted - /// from the base after memory transaction. In addition to - /// producing a chain, post-indexed load produces two values - /// (the result of the load and the result of the base +/- offset - /// computation); a post-indexed store produces one value (the - /// the result of the base +/- offset computation). - /// - enum MemIndexedMode { - UNINDEXED = 0, - PRE_INC, - PRE_DEC, - POST_INC, - POST_DEC, - LAST_INDEXED_MODE - }; - - //===--------------------------------------------------------------------===// - /// LoadExtType enum - This enum defines the three variants of LOADEXT - /// (load with extension). - /// - /// SEXTLOAD loads the integer operand and sign extends it to a larger - /// integer result type. - /// ZEXTLOAD loads the integer operand and zero extends it to a larger - /// integer result type. - /// EXTLOAD is used for three things: floating point extending loads, - /// integer extending loads [the top bits are undefined], and vector - /// extending loads [load into low elt]. - /// - enum LoadExtType { - NON_EXTLOAD = 0, - EXTLOAD, - SEXTLOAD, - ZEXTLOAD, - LAST_LOADEXT_TYPE - }; - - //===--------------------------------------------------------------------===// - /// ISD::CondCode enum - These are ordered carefully to make the bitfields - /// below work out, when considering SETFALSE (something that never exists - /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered - /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal - /// to. If the "N" column is 1, the result of the comparison is undefined if - /// the input is a NAN. - /// - /// All of these (except for the 'always folded ops') should be handled for - /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT, - /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used. - /// - /// Note that these are laid out in a specific order to allow bit-twiddling - /// to transform conditions. - enum CondCode { - // Opcode N U L G E Intuitive operation - SETFALSE, // 0 0 0 0 Always false (always folded) - SETOEQ, // 0 0 0 1 True if ordered and equal - SETOGT, // 0 0 1 0 True if ordered and greater than - SETOGE, // 0 0 1 1 True if ordered and greater than or equal - SETOLT, // 0 1 0 0 True if ordered and less than - SETOLE, // 0 1 0 1 True if ordered and less than or equal - SETONE, // 0 1 1 0 True if ordered and operands are unequal - SETO, // 0 1 1 1 True if ordered (no nans) - SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y) - SETUEQ, // 1 0 0 1 True if unordered or equal - SETUGT, // 1 0 1 0 True if unordered or greater than - SETUGE, // 1 0 1 1 True if unordered, greater than, or equal - SETULT, // 1 1 0 0 True if unordered or less than - SETULE, // 1 1 0 1 True if unordered, less than, or equal - SETUNE, // 1 1 1 0 True if unordered or not equal - SETTRUE, // 1 1 1 1 Always true (always folded) - // Don't care operations: undefined if the input is a nan. - SETFALSE2, // 1 X 0 0 0 Always false (always folded) - SETEQ, // 1 X 0 0 1 True if equal - SETGT, // 1 X 0 1 0 True if greater than - SETGE, // 1 X 0 1 1 True if greater than or equal - SETLT, // 1 X 1 0 0 True if less than - SETLE, // 1 X 1 0 1 True if less than or equal - SETNE, // 1 X 1 1 0 True if not equal - SETTRUE2, // 1 X 1 1 1 Always true (always folded) - - SETCC_INVALID // Marker value. - }; - - /// isSignedIntSetCC - Return true if this is a setcc instruction that - /// performs a signed comparison when used with integer operands. - inline bool isSignedIntSetCC(CondCode Code) { - return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE; - } - - /// isUnsignedIntSetCC - Return true if this is a setcc instruction that - /// performs an unsigned comparison when used with integer operands. - inline bool isUnsignedIntSetCC(CondCode Code) { - return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE; - } - - /// isTrueWhenEqual - Return true if the specified condition returns true if - /// the two operands to the condition are equal. Note that if one of the two - /// operands is a NaN, this value is meaningless. - inline bool isTrueWhenEqual(CondCode Cond) { - return ((int)Cond & 1) != 0; - } - - /// getUnorderedFlavor - This function returns 0 if the condition is always - /// false if an operand is a NaN, 1 if the condition is always true if the - /// operand is a NaN, and 2 if the condition is undefined if the operand is a - /// NaN. - inline unsigned getUnorderedFlavor(CondCode Cond) { - return ((int)Cond >> 3) & 3; - } - - /// getSetCCInverse - Return the operation corresponding to !(X op Y), where - /// 'op' is a valid SetCC operation. - CondCode getSetCCInverse(CondCode Operation, bool isInteger); - - /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X) - /// when given the operation for (X op Y). - CondCode getSetCCSwappedOperands(CondCode Operation); - - /// getSetCCOrOperation - Return the result of a logical OR between different - /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This - /// function returns SETCC_INVALID if it is not possible to represent the - /// resultant comparison. - CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger); - - /// getSetCCAndOperation - Return the result of a logical AND between - /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This - /// function returns SETCC_INVALID if it is not possible to represent the - /// resultant comparison. - CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger); - - //===--------------------------------------------------------------------===// - /// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT - /// supports. - enum CvtCode { - CVT_FF, // Float from Float - CVT_FS, // Float from Signed - CVT_FU, // Float from Unsigned - CVT_SF, // Signed from Float - CVT_UF, // Unsigned from Float - CVT_SS, // Signed from Signed - CVT_SU, // Signed from Unsigned - CVT_US, // Unsigned from Signed - CVT_UU, // Unsigned from Unsigned - CVT_INVALID // Marker - Invalid opcode - }; -} // end llvm::ISD namespace - +} // end llvm:ISD namespace //===----------------------------------------------------------------------===// /// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple @@ -1564,7 +837,7 @@ class HandleSDNode : public SDNode { public: // FIXME: Remove the "noinline" attribute once <rdar://problem/5852746> is // fixed. -#ifdef __GNUC__ +#if __GNUC__==4 && __GNUC_MINOR__==2 && defined(__APPLE__) && !defined(__llvm__) explicit __attribute__((__noinline__)) HandleSDNode(SDValue X) #else explicit HandleSDNode(SDValue X) @@ -1867,7 +1140,7 @@ public: }; class GlobalAddressSDNode : public SDNode { - GlobalValue *TheGlobal; + const GlobalValue *TheGlobal; int64_t Offset; unsigned char TargetFlags; friend class SelectionDAG; @@ -1875,7 +1148,7 @@ class GlobalAddressSDNode : public SDNode { int64_t o, unsigned char TargetFlags); public: - GlobalValue *getGlobal() const { return TheGlobal; } + const GlobalValue *getGlobal() const { return TheGlobal; } int64_t getOffset() const { return Offset; } unsigned char getTargetFlags() const { return TargetFlags; } // Return the address space this GlobalAddress belongs to. @@ -1930,15 +1203,15 @@ public: class ConstantPoolSDNode : public SDNode { union { - Constant *ConstVal; + const Constant *ConstVal; MachineConstantPoolValue *MachineCPVal; } Val; int Offset; // It's a MachineConstantPoolValue if top bit is set. unsigned Alignment; // Minimum alignment requirement of CP (not log2 value). unsigned char TargetFlags; friend class SelectionDAG; - ConstantPoolSDNode(bool isTarget, Constant *c, EVT VT, int o, unsigned Align, - unsigned char TF) + ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, + unsigned Align, unsigned char TF) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { @@ -1961,7 +1234,7 @@ public: return (int)Offset < 0; } - Constant *getConstVal() const { + const Constant *getConstVal() const { assert(!isMachineConstantPoolEntry() && "Wrong constantpool type"); return Val.ConstVal; } @@ -2053,6 +1326,21 @@ public: return N->getOpcode() == ISD::SRCVALUE; } }; + +class MDNodeSDNode : public SDNode { + const MDNode *MD; + friend class SelectionDAG; + explicit MDNodeSDNode(const MDNode *md) + : SDNode(ISD::MDNODE_SDNODE, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {} +public: + + const MDNode *getMD() const { return MD; } + + static bool classof(const MDNodeSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::MDNODE_SDNODE; + } +}; class RegisterSDNode : public SDNode { @@ -2072,16 +1360,16 @@ public: }; class BlockAddressSDNode : public SDNode { - BlockAddress *BA; + const BlockAddress *BA; unsigned char TargetFlags; friend class SelectionDAG; - BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba, + BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba, unsigned char Flags) : SDNode(NodeTy, DebugLoc(), getSDVTList(VT)), BA(ba), TargetFlags(Flags) { } public: - BlockAddress *getBlockAddress() const { return BA; } + const BlockAddress *getBlockAddress() const { return BA; } unsigned char getTargetFlags() const { return TargetFlags; } static bool classof(const BlockAddressSDNode *) { return true; } @@ -2588,7 +1876,6 @@ namespace ISD { } } - } // end llvm namespace #endif diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index caefdf4..3c56d0d 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -28,7 +28,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -37,8 +36,6 @@ namespace llvm { /// SlotIndex & SlotIndexes classes for the public interface to this /// information. class IndexListEntry { - private: - static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U, TOMBSTONE_KEY_INDEX = ~0U & ~7U; @@ -66,10 +63,9 @@ namespace llvm { public: IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) { - if (index == EMPTY_KEY_INDEX || index == TOMBSTONE_KEY_INDEX) { - llvm_report_error("Attempt to create invalid index. " - "Available indexes may have been exhausted?."); - } + assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && + "Attempt to create invalid index. " + "Available indexes may have been exhausted?."); } bool isValid() const { diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index b34ac21..90905f5 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -33,7 +33,6 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { - mutable void *UniquingMap; protected: /// TLSDataSection - Section directive for Thread Local data. /// @@ -52,14 +51,9 @@ protected: const MCSection *MergeableConst4Section; const MCSection *MergeableConst8Section; const MCSection *MergeableConst16Section; - -protected: - const MCSection *getELFSection(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind, - bool IsExplicit = false) const; public: - TargetLoweringObjectFileELF() : UniquingMap(0) {} - ~TargetLoweringObjectFileELF(); + TargetLoweringObjectFileELF() {} + ~TargetLoweringObjectFileELF() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); @@ -90,8 +84,6 @@ public: class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { - mutable void *UniquingMap; - const MCSection *CStringSection; const MCSection *UStringSection; const MCSection *TextCoalSection; @@ -108,8 +100,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { const MCSection *LazySymbolPointerSection; const MCSection *NonLazySymbolPointerSection; public: - TargetLoweringObjectFileMachO() : UniquingMap(0) {} - ~TargetLoweringObjectFileMachO(); + TargetLoweringObjectFileMachO() {} + ~TargetLoweringObjectFileMachO() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); @@ -129,20 +121,6 @@ public: virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *) const; - /// getMachOSection - Return the MCSection for the specified mach-o section. - /// This requires the operands to be valid. - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - SectionKind K) const { - return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); - } - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind K) const; - /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak /// text symbols into. const MCSection *getTextCoalSection() const { diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 5caf778..c2ab23e 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -264,6 +264,9 @@ /* Define to 1 if you have the `opendir' function. */ #undef HAVE_OPENDIR +/* Define to 1 if you have the `posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + /* Define to 1 if you have the `powf' function. */ #undef HAVE_POWF diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index 2ac0fca..f4d125b 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -146,6 +146,49 @@ public: return V->getValueID() == Value::InlineAsmVal; } + + // These are helper methods for dealing with flags in the INLINEASM SDNode + // in the backend. + + enum { + Op_InputChain = 0, + Op_AsmString = 1, + Op_MDNode = 2, + Op_FirstOperand = 3, + + Kind_RegUse = 1, + Kind_RegDef = 2, + Kind_Imm = 3, + Kind_Mem = 4, + Kind_RegDefEarlyClobber = 6, + + Flag_MatchingOperand = 0x80000000 + }; + + static unsigned getFlagWord(unsigned Kind, unsigned NumOps) { + assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!"); + return Kind | (NumOps << 3); + } + + /// getFlagWordForMatchingOp - Augment an existing flag word returned by + /// getFlagWord with information indicating that this input operand is tied + /// to a previous output operand. + static unsigned getFlagWordForMatchingOp(unsigned InputFlag, + unsigned MatchedOperandNo) { + return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16); + } + + static unsigned getKind(unsigned Flags) { + return Flags & 7; + } + + static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;} + static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; } + static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; } + static bool isRegDefEarlyClobberKind(unsigned Flag) { + return getKind(Flag) == Kind_RegDefEarlyClobber; + } + /// getNumOperandRegisters - Extract the number of registers field from the /// inline asm operand flag. static unsigned getNumOperandRegisters(unsigned Flag) { @@ -155,9 +198,9 @@ public: /// isUseOperandTiedToDef - Return true if the flag of the inline asm /// operand indicates it is an use operand that's matched to a def operand. static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) { - if ((Flag & 0x80000000) == 0) + if ((Flag & Flag_MatchingOperand) == 0) return false; - Idx = (Flag & ~0x80000000) >> 16; + Idx = (Flag & ~Flag_MatchingOperand) >> 16; return true; } diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index bd8a8c4..5b0e90f 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -105,8 +105,7 @@ namespace llvm { return cast<ConstantInt>( const_cast<Value*>(getOperand(2)))->getZExtValue(); } - const MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); } - MDNode *getVariable() { return cast<MDNode>(getOperand(3)); } + MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const DbgValueInst *) { return true; } diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index a48a1ed..3ca9cb4 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -669,16 +669,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; } -// Align ops -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_ssse3_palign_r : - Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty, - llvm_v1i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_ssse3_palign_r_128 : - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; -} - //===----------------------------------------------------------------------===// // SSE4.1 diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 4354840..afae08b 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -19,6 +19,7 @@ namespace llvm { class LLVMContextImpl; class StringRef; +class Instruction; template <typename T> class SmallVectorImpl; /// This is an important class for using LLVM in a threaded context. It @@ -68,6 +69,15 @@ public: /// setInlineAsmDiagnosticHandler. void *getInlineAsmDiagnosticContext() const; + + /// emitError - Emit an error message to the currently installed error handler + /// with optional location information. This function returns, so code should + /// be prepared to drop the erroneous construct on the floor and "not crash". + /// The generated code need not be correct. The error message will be + /// implicitly prefixed with "error: " and should not end with a ".". + void emitError(unsigned LocCookie, StringRef ErrorStr); + void emitError(const Instruction *I, StringRef ErrorStr); + void emitError(StringRef ErrorStr); }; /// getGlobalContext - Returns a global context. This is for LLVM clients that diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index ae53851..1e2c37a 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -23,6 +23,7 @@ #include "llvm/Analysis/PointerTracking.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/Lint.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" @@ -135,8 +136,8 @@ namespace { (void) llvm::createSSIPass(); (void) llvm::createSSIEverythingPass(); (void) llvm::createGEPSplitterPass(); - (void) llvm::createSCCVNPass(); (void) llvm::createABCDPass(); + (void) llvm::createLintPass(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h new file mode 100644 index 0000000..dded255 --- /dev/null +++ b/include/llvm/MC/EDInstInfo.h @@ -0,0 +1,29 @@ +//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef EDINSTINFO_H +#define EDINSTINFO_H + +#include "llvm/System/DataTypes.h" + +namespace llvm { + +#define EDIS_MAX_OPERANDS 13 +#define EDIS_MAX_SYNTAXES 2 + +struct EDInstInfo { + uint8_t instructionType; + uint8_t numOperands; + uint8_t operandTypes[EDIS_MAX_OPERANDS]; + uint8_t operandFlags[EDIS_MAX_OPERANDS]; + const char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 33def86..f57f642 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -97,7 +97,11 @@ namespace llvm { /// AllowNameToStartWithDigit - This is true if the assembler allows symbol /// names to start with a digit (e.g., "0x0021"). This defaults to false. bool AllowNameToStartWithDigit; - + + /// AllowPeriodsInName - This is true if the assembler allows periods in + /// symbol names. This defaults to true. + bool AllowPeriodsInName; + //===--- Data Emission Directives -------------------------------------===// /// ZeroDirective - this should be set to the directive used to get some @@ -280,7 +284,7 @@ namespace llvm { /// getNonexecutableStackSection - Targets can implement this method to /// specify a section to switch to if the translation unit doesn't have any /// trampolines that require an executable stack. - virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const { + virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{ return 0; } @@ -341,6 +345,9 @@ namespace llvm { bool doesAllowNameToStartWithDigit() const { return AllowNameToStartWithDigit; } + bool doesAllowPeriodsInName() const { + return AllowPeriodsInName; + } const char *getZeroDirective() const { return ZeroDirective; } diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 968d55f..4434341 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCCONTEXT_H #define LLVM_MC_MCCONTEXT_H +#include "llvm/MC/SectionKind.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" @@ -21,6 +22,7 @@ namespace llvm { class MCSymbol; class StringRef; class Twine; + class MCSectionMachO; /// MCContext - Context object for machine code objects. This class owns all /// of the sections that it creates. @@ -47,6 +49,8 @@ namespace llvm { /// We use a bump pointer allocator to avoid the need to track all allocated /// objects. BumpPtrAllocator Allocator; + + void *MachOUniquingMap, *ELFUniquingMap; public: explicit MCContext(const MCAsmInfo &MAI); ~MCContext(); @@ -72,6 +76,29 @@ namespace llvm { MCSymbol *LookupSymbol(StringRef Name) const; /// @} + + /// @name Section Managment + /// @{ + + /// getMachOSection - Return the MCSection for the specified mach-o section. + /// This requires the operands to be valid. + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + unsigned Reserved2, + SectionKind K); + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + SectionKind K) { + return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); + } + + const MCSection *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind, + bool IsExplicit = false); + + /// @} void *Allocate(unsigned Size, unsigned Align = 8) { return Allocator.Allocate(Size, Align); diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index ffa0e41..dfb8ed5 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -16,6 +16,8 @@ namespace llvm { class MCInst; class MemoryObject; class raw_ostream; + +struct EDInstInfo; /// MCDisassembler - Superclass for all disassemblers. Consumes a memory region /// and provides an array of assembly instructions. @@ -43,7 +45,15 @@ public: const MemoryObject ®ion, uint64_t address, raw_ostream &vStream) const = 0; -}; + + /// getEDInfo - Returns the enhanced insturction information corresponding to + /// the disassembler. + /// + /// @return - An array of instruction information, with one entry for + /// each MCInst opcode this disassembler returns. + /// NULL if there is no info for this target. + virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } +}; } // namespace llvm diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index f70a3d1..522ee77 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -49,7 +49,7 @@ protected: // Can only create subclasses. public: virtual ~MCObjectWriter(); - bool isLittleEndian() { return IsLittleEndian; } + bool isLittleEndian() const { return IsLittleEndian; } raw_ostream &getStream() { return OS; } diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index 23f4a1f..7a78906 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -14,7 +14,6 @@ #ifndef ASMPARSER_H #define ASMPARSER_H -#include <vector> #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/AsmCond.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -22,6 +21,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/ADT/StringMap.h" +#include <vector> namespace llvm { class AsmCond; @@ -50,10 +50,6 @@ private: AsmCond TheCondState; std::vector<AsmCond> TheCondStack; - // FIXME: Figure out where this should leave, the code is a copy of that which - // is also used by TargetLoweringObjectFile. - mutable void *SectionUniquingMap; - /// DirectiveMap - This is a table handlers for directives. Each handler is /// invoked after the directive identifier is read and is responsible for /// parsing and validating the rest of the directive. The handler is passed @@ -97,13 +93,6 @@ public: private: MCSymbol *CreateSymbol(StringRef Name); - // FIXME: See comment on SectionUniquingMap. - const MCSection *getMachOSection(const StringRef &Segment, - const StringRef &Section, - unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind Kind) const; - bool ParseStatement(); bool TokError(const char *Msg); @@ -113,8 +102,6 @@ private: /// EnterIncludeFile - Enter the specified file. This returns true on failure. bool EnterIncludeFile(const std::string &Filename); - bool ParseConditionalAssemblyDirectives(StringRef Directive, - SMLoc DirectiveLoc); void EatToEndOfStatement(); bool ParseAssignment(const StringRef &Name); diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 043c363..075b69b 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -42,7 +42,7 @@ public: Plus, Minus, Tilde, Slash, // '/' LParen, RParen, LBrac, RBrac, LCurly, RCurly, - Star, Comma, Dollar, Equal, EqualEqual, + Star, Dot, Comma, Dollar, Equal, EqualEqual, Pipe, PipePipe, Caret, Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash, diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index e550cd2..7054668 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -36,16 +36,14 @@ class MCSectionELF : public MCSection { /// explicit section specified. bool IsExplicit; -protected: +private: + friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, bool isExplicit) : MCSection(K), SectionName(Section), Type(type), Flags(flags), IsExplicit(isExplicit) {} + ~MCSectionELF(); public: - - static MCSectionELF *Create(StringRef Section, unsigned Type, - unsigned Flags, SectionKind K, bool isExplicit, - MCContext &Ctx); /// ShouldOmitSectionDirective - Decides whether a '.section' directive /// should be printed before the section name @@ -153,40 +151,33 @@ public: // This section holds Thread-Local Storage. SHF_TLS = 0x400U, + + + // Start of target-specific flags. + + /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped + /// together by the linker to form the constant pool and the cp register is + /// set to the start of the constant pool by the boot code. + XCORE_SHF_CP_SECTION = 0x800U, - /// FIRST_TARGET_DEP_FLAG - This is the first flag that subclasses are - /// allowed to specify. - FIRST_TARGET_DEP_FLAG = 0x800U, - - /// TARGET_INDEP_SHF - This is the bitmask for all the target independent - /// section flags. Targets can define their own target flags above these. - /// If they do that, they should implement their own MCSectionELF subclasses - /// and implement the virtual method hooks below to handle printing needs. - TARGET_INDEP_SHF = FIRST_TARGET_DEP_FLAG-1U + /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped + /// together by the linker to form the data section and the dp register is + /// set to the start of the section by the boot code. + XCORE_SHF_DP_SECTION = 0x1000U }; StringRef getSectionName() const { return SectionName; } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; + void PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS) const; /// isBaseAddressKnownZero - We know that non-allocatable sections (like /// debug info) have a base of zero. virtual bool isBaseAddressKnownZero() const { return (getFlags() & SHF_ALLOC) == 0; } - - /// PrintTargetSpecificSectionFlags - Targets that define their own - /// MCSectionELF subclasses with target specific section flags should - /// implement this method if they end up adding letters to the attributes - /// list. - virtual void PrintTargetSpecificSectionFlags(const MCAsmInfo &MAI, - raw_ostream &OS) const { - } - - }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 5839c28..f3bc8ed 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -34,30 +34,10 @@ class MCSectionMachO : public MCSection { unsigned Reserved2; MCSectionMachO(StringRef Segment, StringRef Section, - unsigned TAA, unsigned reserved2, SectionKind K) - : MCSection(K), TypeAndAttributes(TAA), Reserved2(reserved2) { - assert(Segment.size() <= 16 && Section.size() <= 16 && - "Segment or section string too long"); - for (unsigned i = 0; i != 16; ++i) { - if (i < Segment.size()) - SegmentName[i] = Segment[i]; - else - SegmentName[i] = 0; - - if (i < Section.size()) - SectionName[i] = Section[i]; - else - SectionName[i] = 0; - } - } + unsigned TAA, unsigned reserved2, SectionKind K); + friend class MCContext; public: - static MCSectionMachO *Create(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind K, MCContext &Ctx); - /// These are the section type and attributes fields. A MachO section can /// have only one Type, but can have any of the attributes specified. enum { diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index ff3e03e..64ab6b7 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -91,7 +91,7 @@ class MDNode : public Value, public FoldingSetNode { FunctionLocalBit = 1 << 0, /// NotUniquedBit - This is set on MDNodes that are not uniqued because they - /// have a null perand. + /// have a null operand. NotUniquedBit = 1 << 1, /// DestroyFlag - This bit is set by destroy() so the destructor can assert diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index 148d47e..4a7251f 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -236,4 +236,6 @@ inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { offsetof(S, x))); } +inline void operator delete(void *, llvm::BumpPtrAllocator &) {} + #endif // LLVM_SUPPORT_ALLOCATOR_H diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index 57699c7..f07c719 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -25,28 +25,29 @@ namespace llvm { // BasicBlock pred_iterator definition //===----------------------------------------------------------------------===// -template <class _Ptr, class _USE_iterator> // Predecessor Iterator +template <class Ptr, class USE_iterator> // Predecessor Iterator class PredIterator : public std::iterator<std::forward_iterator_tag, - _Ptr, ptrdiff_t> { - typedef std::iterator<std::forward_iterator_tag, _Ptr, ptrdiff_t> super; - _USE_iterator It; -public: - typedef PredIterator<_Ptr,_USE_iterator> _Self; - typedef typename super::pointer pointer; + Ptr, ptrdiff_t> { + typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super; + typedef PredIterator<Ptr, USE_iterator> Self; + USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example PHI nodes)... + // Loop to ignore non terminator uses (for example PHI nodes). while (!It.atEnd() && !isa<TerminatorInst>(*It)) ++It; } - inline PredIterator(_Ptr *bb) : It(bb->use_begin()) { +public: + typedef typename super::pointer pointer; + + explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { advancePastNonTerminators(); } - inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {} + inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {} - inline bool operator==(const _Self& x) const { return It == x.It; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + inline bool operator==(const Self& x) const { return It == x.It; } + inline bool operator!=(const Self& x) const { return !operator==(x); } inline pointer operator*() const { assert(!It.atEnd() && "pred_iterator out of range!"); @@ -54,14 +55,14 @@ public: } inline pointer *operator->() const { return &(operator*()); } - inline _Self& operator++() { // Preincrement + inline Self& operator++() { // Preincrement assert(!It.atEnd() && "pred_iterator out of range!"); ++It; advancePastNonTerminators(); return *this; } - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + inline Self operator++(int) { // Postincrement + Self tmp = *this; ++*this; return tmp; } }; @@ -90,12 +91,17 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, const Term_ Term; unsigned idx; typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super; + typedef SuccIterator<Term_, BB_> Self; + + inline bool index_is_valid(int idx) { + return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); + } + public: - typedef SuccIterator<Term_, BB_> _Self; typedef typename super::pointer pointer; // TODO: This can be random access iterator, only operator[] missing. - inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator + explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator assert(T && "getTerminator returned null!"); } inline SuccIterator(Term_ T, bool) // end iterator @@ -103,78 +109,74 @@ public: assert(T && "getTerminator returned null!"); } - inline const _Self &operator=(const _Self &I) { + inline const Self &operator=(const Self &I) { assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); idx = I.idx; return *this; } - inline bool index_is_valid (int idx) { - return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); - } - /// getSuccessorIndex - This is used to interface between code that wants to /// operate on terminator instructions directly. unsigned getSuccessorIndex() const { return idx; } - inline bool operator==(const _Self& x) const { return idx == x.idx; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + inline bool operator==(const Self& x) const { return idx == x.idx; } + inline bool operator!=(const Self& x) const { return !operator==(x); } inline pointer operator*() const { return Term->getSuccessor(idx); } inline pointer operator->() const { return operator*(); } - inline _Self& operator++() { ++idx; return *this; } // Preincrement + inline Self& operator++() { ++idx; return *this; } // Preincrement - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + inline Self operator++(int) { // Postincrement + Self tmp = *this; ++*this; return tmp; } - inline _Self& operator--() { --idx; return *this; } // Predecrement - inline _Self operator--(int) { // Postdecrement - _Self tmp = *this; --*this; return tmp; + inline Self& operator--() { --idx; return *this; } // Predecrement + inline Self operator--(int) { // Postdecrement + Self tmp = *this; --*this; return tmp; } - inline bool operator<(const _Self& x) const { + inline bool operator<(const Self& x) const { assert(Term == x.Term && "Cannot compare iterators of different blocks!"); return idx < x.idx; } - inline bool operator<=(const _Self& x) const { + inline bool operator<=(const Self& x) const { assert(Term == x.Term && "Cannot compare iterators of different blocks!"); return idx <= x.idx; } - inline bool operator>=(const _Self& x) const { + inline bool operator>=(const Self& x) const { assert(Term == x.Term && "Cannot compare iterators of different blocks!"); return idx >= x.idx; } - inline bool operator>(const _Self& x) const { + inline bool operator>(const Self& x) const { assert(Term == x.Term && "Cannot compare iterators of different blocks!"); return idx > x.idx; } - inline _Self& operator+=(int Right) { + inline Self& operator+=(int Right) { unsigned new_idx = idx + Right; assert(index_is_valid(new_idx) && "Iterator index out of bound"); idx = new_idx; return *this; } - inline _Self operator+(int Right) { - _Self tmp = *this; + inline Self operator+(int Right) { + Self tmp = *this; tmp += Right; return tmp; } - inline _Self& operator-=(int Right) { + inline Self& operator-=(int Right) { return operator+=(-Right); } - inline _Self operator-(int Right) { + inline Self operator-(int Right) { return operator+(-Right); } - inline int operator-(const _Self& x) { + inline int operator-(const Self& x) { assert(Term == x.Term && "Cannot work on iterators of different blocks!"); int distance = idx - x.idx; return distance; @@ -185,14 +187,14 @@ public: // be modified are not available. // // inline pointer operator[](int offset) { - // _Self tmp = *this; + // Self tmp = *this; // tmp += offset; // return tmp.operator*(); // } /// Get the source BB of this iterator. inline BB_ *getSource() { - return Term->getParent(); + return Term->getParent(); } }; diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index 9f527e2..0650b61 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -30,7 +30,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/BasicBlock.h" #include "llvm/CallingConv.h" -#include "llvm/Instruction.h" +#include "llvm/Instructions.h" namespace llvm { @@ -150,6 +150,108 @@ public: bool arg_empty() const { return arg_end() == arg_begin(); } unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); } + /// getType - Return the type of the instruction that generated this call site + /// + const Type *getType() const { return (*this)->getType(); } + + /// getCaller - Return the caller function for this call site + /// + FunTy *getCaller() const { return (*this)->getParent()->getParent(); } + +#define CALLSITE_DELEGATE_GETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + return isCall() \ + ? cast<CallInst>(II)->METHOD \ + : cast<InvokeInst>(II)->METHOD + +#define CALLSITE_DELEGATE_SETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + if (isCall()) \ + cast<CallInst>(II)->METHOD; \ + else \ + cast<InvokeInst>(II)->METHOD + + /// getCallingConv/setCallingConv - get or set the calling convention of the + /// call. + CallingConv::ID getCallingConv() const { + CALLSITE_DELEGATE_GETTER(getCallingConv()); + } + void setCallingConv(CallingConv::ID CC) { + CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); + } + + /// getAttributes/setAttributes - get or set the parameter attributes of + /// the call. + const AttrListPtr &getAttributes() const { + CALLSITE_DELEGATE_GETTER(getAttributes()); + } + void setAttributes(const AttrListPtr &PAL) { + CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); + } + + /// paramHasAttr - whether the call or the callee has the given attribute. + bool paramHasAttr(uint16_t i, Attributes attr) const { + CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr)); + } + + /// @brief Extract the alignment for a call or parameter (0=unknown). + uint16_t getParamAlignment(uint16_t i) const { + CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); + } + + /// @brief Return true if the call should not be inlined. + bool isNoInline() const { + CALLSITE_DELEGATE_GETTER(isNoInline()); + } + void setIsNoInline(bool Value = true) { + CALLSITE_DELEGATE_GETTER(setIsNoInline(Value)); + } + + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const { + CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); + } + void setDoesNotAccessMemory(bool doesNotAccessMemory = true) { + CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory)); + } + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const { + CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); + } + void setOnlyReadsMemory(bool onlyReadsMemory = true) { + CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory)); + } + + /// @brief Determine if the call cannot return. + bool doesNotReturn() const { + CALLSITE_DELEGATE_GETTER(doesNotReturn()); + } + void setDoesNotReturn(bool doesNotReturn = true) { + CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn)); + } + + /// @brief Determine if the call cannot unwind. + bool doesNotThrow() const { + CALLSITE_DELEGATE_GETTER(doesNotThrow()); + } + void setDoesNotThrow(bool doesNotThrow = true) { + CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow)); + } + +#undef CALLSITE_DELEGATE_GETTER +#undef CALLSITE_DELEGATE_SETTER + + /// hasArgument - Returns true if this CallSite passes the given Value* as an + /// argument to the called function. + bool hasArgument(const Value *Arg) const { + for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; + ++AI) + if (AI->get() == Arg) + return true; + return false; + } + private: /// Returns the operand number of the first argument unsigned getArgumentOffset() const { @@ -179,24 +281,24 @@ private: /// ImmutableCallSite - establish a view to a call site for examination class ImmutableCallSite : public CallSiteBase<> { - typedef CallSiteBase<> _Base; + typedef CallSiteBase<> Base; public: - ImmutableCallSite(const Value* V) : _Base(V) {} - ImmutableCallSite(const CallInst *CI) : _Base(CI) {} - ImmutableCallSite(const InvokeInst *II) : _Base(II) {} - ImmutableCallSite(const Instruction *II) : _Base(II) {} + ImmutableCallSite(const Value* V) : Base(V) {} + ImmutableCallSite(const CallInst *CI) : Base(CI) {} + ImmutableCallSite(const InvokeInst *II) : Base(II) {} + ImmutableCallSite(const Instruction *II) : Base(II) {} }; class CallSite : public CallSiteBase<Function, Value, User, Instruction, CallInst, InvokeInst, User::op_iterator> { typedef CallSiteBase<Function, Value, User, Instruction, - CallInst, InvokeInst, User::op_iterator> _Base; + CallInst, InvokeInst, User::op_iterator> Base; public: CallSite() {} - CallSite(_Base B) : _Base(B) {} - CallSite(CallInst *CI) : _Base(CI) {} - CallSite(InvokeInst *II) : _Base(II) {} - CallSite(Instruction *II) : _Base(II) {} + CallSite(Base B) : Base(B) {} + CallSite(CallInst *CI) : Base(CI) {} + CallSite(InvokeInst *II) : Base(II) {} + CallSite(Instruction *II) : Base(II) {} bool operator==(const CallSite &CS) const { return I == CS.I; } bool operator!=(const CallSite &CS) const { return I != CS.I; } @@ -207,57 +309,9 @@ public: /// NOT a call site. /// static CallSite get(Value *V) { - return _Base::get(V); + return Base::get(V); } - /// getCallingConv/setCallingConv - get or set the calling convention of the - /// call. - CallingConv::ID getCallingConv() const; - void setCallingConv(CallingConv::ID CC); - - /// getAttributes/setAttributes - get or set the parameter attributes of - /// the call. - const AttrListPtr &getAttributes() const; - void setAttributes(const AttrListPtr &PAL); - - /// paramHasAttr - whether the call or the callee has the given attribute. - bool paramHasAttr(uint16_t i, Attributes attr) const; - - /// @brief Extract the alignment for a call or parameter (0=unknown). - uint16_t getParamAlignment(uint16_t i) const; - - /// @brief Return true if the call should not be inlined. - bool isNoInline() const; - void setIsNoInline(bool Value = true); - - /// @brief Determine if the call does not access memory. - bool doesNotAccessMemory() const; - void setDoesNotAccessMemory(bool doesNotAccessMemory = true); - - /// @brief Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const; - void setOnlyReadsMemory(bool onlyReadsMemory = true); - - /// @brief Determine if the call cannot return. - bool doesNotReturn() const; - void setDoesNotReturn(bool doesNotReturn = true); - - /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const; - void setDoesNotThrow(bool doesNotThrow = true); - - /// getType - Return the type of the instruction that generated this call site - /// - const Type *getType() const { return (*this)->getType(); } - - /// getCaller - Return the caller function for this call site - /// - Function *getCaller() const { return (*this)->getParent()->getParent(); } - - /// hasArgument - Returns true if this CallSite passes the given Value* as an - /// argument to the called function. - bool hasArgument(const Value *Arg) const; - bool operator<(const CallSite &CS) const { return getInstruction() < CS.getInstruction(); } diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 31f4fd2..3d25e03 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -230,6 +230,7 @@ enum dwarf_constants { DW_AT_APPLE_block = 0x3fe4, DW_AT_APPLE_major_runtime_vers = 0x3fe5, DW_AT_APPLE_runtime_class = 0x3fe6, + DW_AT_APPLE_omit_frame_ptr = 0x3fe7, // Attribute form encodings DW_FORM_addr = 0x01, diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index e747c7a..d09db39 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -99,6 +99,12 @@ enum { ET_HIPROC = 0xffff // Processor-specific }; +// Versioning +enum { + EV_NONE = 0, + EV_CURRENT = 1 +}; + // Machine architectures enum { EM_NONE = 0, // No machine @@ -129,6 +135,11 @@ enum { ELFDATA2MSB = 2 // Big-endian object file }; +// OS ABI identification -- unused. +enum { + ELFOSABI_NONE = 0 +}; + // Section header. struct Elf32_Shdr { Elf32_Word sh_name; // Section name (index into string table) diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h index 4d24ada..ffcb482 100644 --- a/include/llvm/Support/ErrorHandling.h +++ b/include/llvm/Support/ErrorHandling.h @@ -1,4 +1,4 @@ -//===- llvm/Support/ErrorHandling.h - Callbacks for errors ------*- C++ -*-===// +//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines an API used to indicate error conditions. -// Callbacks can be registered for these errors through this API. +// This file defines an API used to indicate fatal error conditions. Non-fatal +// errors (most of them) should be handled through LLVMContext. // //===----------------------------------------------------------------------===// @@ -22,10 +22,10 @@ namespace llvm { class Twine; /// An error handler callback. - typedef void (*llvm_error_handler_t)(void *user_data, - const std::string& reason); + typedef void (*fatal_error_handler_t)(void *user_data, + const std::string& reason); - /// llvm_instal_error_handler - Installs a new error handler to be used + /// install_fatal_error_handler - Installs a new error handler to be used /// whenever a serious (non-recoverable) error is encountered by LLVM. /// /// If you are using llvm_start_multithreaded, you should register the handler @@ -44,13 +44,13 @@ namespace llvm { /// /// \param user_data - An argument which will be passed to the install error /// handler. - void llvm_install_error_handler(llvm_error_handler_t handler, - void *user_data = 0); + void install_fatal_error_handler(fatal_error_handler_t handler, + void *user_data = 0); /// Restores default error handling behaviour. /// This must not be called between llvm_start_multithreaded() and /// llvm_stop_multithreaded(). - void llvm_remove_error_handler(); + void remove_fatal_error_handler(); /// Reports a serious error, calling any installed error handler. These /// functions are intended to be used for error conditions which are outside @@ -60,9 +60,9 @@ namespace llvm { /// standard error, followed by a newline. /// After the error handler is called this function will call exit(1), it /// does not return. - NORETURN void llvm_report_error(const char *reason); - NORETURN void llvm_report_error(const std::string &reason); - NORETURN void llvm_report_error(const Twine &reason); + NORETURN void report_fatal_error(const char *reason); + NORETURN void report_fatal_error(const std::string &reason); + NORETURN void report_fatal_error(const Twine &reason); /// This function calls abort(), and prints the optional message to stderr. /// Use the llvm_unreachable macro (that adds location info), instead of diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 28fa92f..13e6682 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -174,7 +174,8 @@ public: unsigned i = 0, e = DTraits.numEdgeDestLabels(Node); for (; i != e && i != 64; ++i) { if (i) O << "|"; - O << "<d" << i << ">" << DTraits.getEdgeDestLabel(Node, i); + O << "<d" << i << ">" + << DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i)); } if (i != e) @@ -230,7 +231,7 @@ public: for (unsigned i = 0; i != NumEdgeSources; ++i) { if (i) O << "|"; O << "<s" << i << ">"; - if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i]; + if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]); } O << "}}"; } diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 660c9f8..1fd965d 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -432,12 +432,19 @@ public: return Folder.CreateFRem(LC, RC); return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); } + Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateShl(LC, RC); return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); } + Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateShl(LC, RHSC); + return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name); + } Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") { Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); if (Constant *LC = dyn_cast<Constant>(LHS)) @@ -451,23 +458,35 @@ public: return Folder.CreateLShr(LC, RC); return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); } + Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateLShr(LC, RHSC); + return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name); + } Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); if (Constant *LC = dyn_cast<Constant>(LHS)) return Folder.CreateLShr(LC, RHSC); return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name); } - + Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateAShr(LC, RC); return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } + Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateAShr(LC, RHSC); + return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name); + } Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); if (Constant *LC = dyn_cast<Constant>(LHS)) - return Folder.CreateSShr(LC, RHSC); + return Folder.CreateAShr(LC, RHSC); return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name); } @@ -480,6 +499,19 @@ public: } return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } + Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateAnd(LC, RHSC); + return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name); + } + Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateAnd(LC, RHSC); + return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name); + } + Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *RC = dyn_cast<Constant>(RHS)) { if (RC->isNullValue()) @@ -489,12 +521,37 @@ public: } return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } + Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateOr(LC, RHSC); + return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name); + } + Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateOr(LC, RHSC); + return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name); + } + Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateXor(LC, RC); return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); } + Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateXor(LC, RHSC); + return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name); + } + Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast<Constant>(LHS)) + return Folder.CreateXor(LC, RHSC); + return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name); + } Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name = "") { diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h index 2a43c5f..0dfc302 100644 --- a/include/llvm/Support/IRReader.h +++ b/include/llvm/Support/IRReader.h @@ -38,8 +38,7 @@ namespace llvm { std::string ErrMsg; Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg); if (M == 0) { - Err = SMDiagnostic(SMLoc(), Buffer->getBufferIdentifier(), -1, -1, - ErrMsg, ""); + Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg); // ParseBitcodeFile does not take ownership of the Buffer in the // case of an error. delete Buffer; @@ -60,8 +59,8 @@ namespace llvm { std::string ErrMsg; MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); if (F == 0) { - Err = SMDiagnostic(SMLoc(), Filename, -1, -1, - "Could not open input file '" + Filename + "'", ""); + Err = SMDiagnostic(Filename, + "Could not open input file '" + Filename + "'"); return 0; } @@ -82,8 +81,7 @@ namespace llvm { // ParseBitcodeFile does not take ownership of the Buffer. delete Buffer; if (M == 0) - Err = SMDiagnostic(SMLoc(), Buffer->getBufferIdentifier(), - -1, -1, ErrMsg, ""); + Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg); return M; } @@ -99,8 +97,8 @@ namespace llvm { std::string ErrMsg; MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); if (F == 0) { - Err = SMDiagnostic(SMLoc(), Filename, -1, -1, - "Could not open input file '" + Filename + "'", ""); + Err = SMDiagnostic(Filename, + "Could not open input file '" + Filename + "'"); return 0; } diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h index 49f7753..34ab874 100644 --- a/include/llvm/Support/RecyclingAllocator.h +++ b/include/llvm/Support/RecyclingAllocator.h @@ -63,4 +63,11 @@ inline void *operator new(size_t, return Allocator.Allocate(); } +template<class AllocatorType, class T, size_t Size, size_t Align> +inline void operator delete(void *E, + llvm::RecyclingAllocator<AllocatorType, + T, Size, Align> &A) { + A.Deallocate(E); +} + #endif diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 3e66762..9cd35d1 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -148,6 +148,7 @@ private: /// SMDiagnostic - Instances of this class encapsulate one diagnostic report, /// allowing printing to a raw_ostream as a caret diagnostic. class SMDiagnostic { + const SourceMgr *SM; SMLoc Loc; std::string Filename; int LineNo, ColumnNo; @@ -155,15 +156,25 @@ class SMDiagnostic { unsigned ShowLine : 1; public: - SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {} - SMDiagnostic(SMLoc L, const std::string &FN, int Line, int Col, + // Null diagnostic. + SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {} + // Diagnostic with no location (e.g. file not found, command line arg error). + SMDiagnostic(const std::string &filename, const std::string &Msg, + bool showline = true) + : SM(0), Loc(), Filename(filename), LineNo(-1), ColumnNo(-1), + Message(Msg), LineContents(""), ShowLine(showline) {} + + // Diagnostic with a location. + SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, + int Line, int Col, const std::string &Msg, const std::string &LineStr, bool showline = true) - : Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg), + : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg), LineContents(LineStr), ShowLine(showline) {} + const SourceMgr *getSourceMgr() const { return SM; } SMLoc getLoc() const { return Loc; } - const std::string getFilename() { return Filename; } + const std::string &getFilename() { return Filename; } int getLineNo() const { return LineNo; } int getColumnNo() const { return ColumnNo; } const std::string &getMessage() const { return Message; } diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index 130a620..c0cdc35 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -315,7 +315,7 @@ class TrackingVH : public ValueHandleBase { public: TrackingVH() : ValueHandleBase(Tracking) {} - TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, P) {} + TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {} TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {} operator ValueTy*() const { diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index e0de80f..90eaeea 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -96,7 +96,7 @@ public: /// clear_error - Set the flag read by has_error() to false. If the error /// flag is set at the time when this raw_ostream's destructor is called, - /// llvm_report_error is called to report the error. Use clear_error() + /// report_fatal_error is called to report the error. Use clear_error() /// after handling the error to avoid this behavior. void clear_error() { Error = false; diff --git a/include/llvm/System/DataTypes.h.in b/include/llvm/System/DataTypes.h.in index 1f8ce79..6537f30 100644 --- a/include/llvm/System/DataTypes.h.in +++ b/include/llvm/System/DataTypes.h.in @@ -15,7 +15,7 @@ |* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*| |* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *| |* *| -|* No library is required when using these functinons. *| +|* No library is required when using these functions. *| |* *| |*===----------------------------------------------------------------------===*/ diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 462c38f..cc19e0d 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -473,13 +473,22 @@ def DBG_VALUE : Instruction { let Namespace = "TargetOpcode"; let isAsCheapAsAMove = 1; } + +def REG_SEQUENCE : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins variable_ops); + let AsmString = ""; + let Namespace = "TargetOpcode"; + let neverHasSideEffects = 1; + let isAsCheapAsAMove = 1; +} } //===----------------------------------------------------------------------===// -// AsmParser - This class can be implemented by targets that wish to implement +// AsmParser - This class can be implemented by targets that wish to implement // .s file parsing. // -// Subtargets can have multiple different assembly parsers (e.g. AT&T vs Intel +// Subtargets can have multiple different assembly parsers (e.g. AT&T vs Intel // syntax on X86 for example). // class AsmParser { @@ -492,9 +501,13 @@ class AsmParser { // AsmParser class to call on every matched instruction. This can be used to // perform target specific instruction post-processing. string AsmParserInstCleanup = ""; - + + // MatchInstructionName - The name of the instruction matching function to + // generate. + string MatchInstructionName = "MatchInstruction"; + // Variant - AsmParsers can be of multiple different variants. Variants are - // used to support targets that need to parser multiple formats for the + // used to support targets that need to parser multiple formats for the // assembly language. int Variant = 0; diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 4b26beb..143dbcc 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -23,6 +23,8 @@ class CalleeSavedInfo; class LiveVariables; class MCAsmInfo; class MachineMemOperand; +class MDNode; +class MCInst; class SDNode; class SelectionDAG; class TargetRegisterClass; @@ -182,7 +184,7 @@ public: /// store to a stack slot, return true along with the FrameIndex of /// the loaded stack slot and the machine mem operand containing the /// reference. If not, return false. Unlike isStoreToStackSlot, - /// this returns true for any instructions that loads from the + /// this returns true for any instructions that stores to the /// stack. This is just a hint, as some cases may be missed. virtual bool hasStoreToStackSlot(const MachineInstr *MI, const MachineMemOperand *&MMO, @@ -361,6 +363,22 @@ public: return false; } + /// emitFrameIndexDebugValue - Emit a target-dependent form of + /// DBG_VALUE encoding the address of a frame index. Addresses would + /// normally be lowered the same way as other addresses on the target, + /// e.g. in load instructions. For targets that do not support this + /// the debug info is simply lost. + /// If you add this for a target you should handle this DBG_VALUE in the + /// target-specific AsmPrinter code as well; you will probably get invalid + /// assembly output if you don't. + virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, + int FrameIx, + uint64_t Offset, + const MDNode *MDPtr, + DebugLoc dl) const { + return 0; + } + /// foldMemoryOperand - Attempt to fold a load or store of the specified stack /// slot into the specified machine instruction for the specified operand(s). /// If this is possible, a new instruction is returned with the specified @@ -473,6 +491,13 @@ public: virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; + + /// getNoopForMachoTarget - Return the noop instruction to use for a noop. + virtual void getNoopForMachoTarget(MCInst &NopInst) const { + // Default to just using 'nop' string. + } + + /// isPredicated - Returns true if the instruction is already predicated. /// virtual bool isPredicated(const MachineInstr *MI) const { diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h index 420fa94..3dfa8bc 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/Target/TargetInstrItineraries.h @@ -47,10 +47,24 @@ namespace llvm { /// indicate that the instruction requires multiple stages at the /// same time. /// +/// FU reservation can be of two different kinds: +/// - FUs which instruction actually requires +/// - FUs which instruction just reserves. Reserved unit is not available for +/// execution of other instruction. However, several instructions can reserve +/// the same unit several times. +/// Such two types of units reservation is used to model instruction domain +/// change stalls, FUs using the same resource (e.g. same register file), etc. + struct InstrStage { + enum ReservationKinds { + Required = 0, + Reserved = 1 + }; + unsigned Cycles_; ///< Length of stage in machine cycles unsigned Units_; ///< Choice of functional units - int NextCycles_; ///< Number of machine cycles to next stage + int NextCycles_; ///< Number of machine cycles to next stage + ReservationKinds Kind_; ///< Kind of the FU reservation /// getCycles - returns the number of cycles the stage is occupied unsigned getCycles() const { @@ -62,6 +76,10 @@ struct InstrStage { return Units_; } + ReservationKinds getReservationKind() const { + return Kind_; + } + /// getNextCycles - returns the number of cycles from the start of /// this stage to the start of the next stage in the itinerary unsigned getNextCycles() const { diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 1a94b44..4ea6c94 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -104,12 +104,13 @@ public: }; /// NOTE: The constructor takes ownership of TLOF. - explicit TargetLowering(TargetMachine &TM, TargetLoweringObjectFile *TLOF); + explicit TargetLowering(const TargetMachine &TM, + const TargetLoweringObjectFile *TLOF); virtual ~TargetLowering(); - TargetMachine &getTargetMachine() const { return TM; } + const TargetMachine &getTargetMachine() const { return TM; } const TargetData *getTargetData() const { return TD; } - TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } + const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } @@ -172,6 +173,13 @@ public: return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0; } + /// isTypeSynthesizable - Return true if it's OK for the compiler to create + /// new operations of this type. All Legal types are synthesizable except + /// MMX vector types on X86. Non-Legal types are not synthesizable. + bool isTypeSynthesizable(EVT VT) const { + return isTypeLegal(VT) && Synthesizable[VT.getSimpleVT().SimpleTy]; + } + class ValueTypeActionImpl { /// ValueTypeActions - This is a bitvector that contains two bits for each /// value type, where the two bits correspond to the LegalizeAction enum. @@ -180,16 +188,8 @@ public: uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2]; public: ValueTypeActionImpl() { - ValueTypeActions[0] = ValueTypeActions[1] = 0; - ValueTypeActions[2] = ValueTypeActions[3] = 0; + std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); } - ValueTypeActionImpl(const ValueTypeActionImpl &RHS) { - ValueTypeActions[0] = RHS.ValueTypeActions[0]; - ValueTypeActions[1] = RHS.ValueTypeActions[1]; - ValueTypeActions[2] = RHS.ValueTypeActions[2]; - ValueTypeActions[3] = RHS.ValueTypeActions[3]; - } - LegalizeAction getTypeAction(LLVMContext &Context, EVT VT) const { if (VT.isExtended()) { if (VT.isVector()) { @@ -317,7 +317,7 @@ public: }; virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info, - CallInst &I, unsigned Intrinsic) { + const CallInst &I, unsigned Intrinsic) const { return false; } @@ -638,12 +638,14 @@ public: /// probably because the source does not need to be loaded. If /// 'NonScalarIntSafe' is true, that means it's safe to return a /// non-scalar-integer type, e.g. empty string source, constant, or loaded - /// from memory. It returns EVT::Other if SelectionDAG should be responsible - /// for determining it. + /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is + /// constant so it does not need to be loaded. + /// It returns EVT::Other if the type should be determined using generic + /// target-independent logic. virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign, - bool NonScalarIntSafe, - SelectionDAG &DAG) const { + bool NonScalarIntSafe, bool MemcpyStrSrc, + MachineFunction &MF) const { return MVT::Other; } @@ -773,12 +775,19 @@ public: /// that want to combine struct TargetLoweringOpt { SelectionDAG &DAG; + bool LegalTys; + bool LegalOps; bool ShrinkOps; SDValue Old; SDValue New; - explicit TargetLoweringOpt(SelectionDAG &InDAG, bool Shrink = false) : - DAG(InDAG), ShrinkOps(Shrink) {} + explicit TargetLoweringOpt(SelectionDAG &InDAG, + bool LT, bool LO, + bool Shrink = false) : + DAG(InDAG), LegalTys(LT), LegalOps(LO), ShrinkOps(Shrink) {} + + bool LegalTypes() const { return LegalTys; } + bool LegalOperations() const { return LegalOps; } bool CombineTo(SDValue O, SDValue N) { Old = O; @@ -862,7 +871,7 @@ public: /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the /// node is a GlobalAddress + offset. virtual bool - isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const; + isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const; /// PerformDAGCombine - This method will be invoked for all target nodes and /// for any target-independent nodes that the target has registered with @@ -878,6 +887,22 @@ public: /// more complex transformations. /// virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + + /// isTypeDesirableForOp - Return true if the target has native support for + /// the specified value type and it is 'desirable' to use the type for the + /// given node type. e.g. On x86 i16 is legal, but undesirable since i16 + /// instruction encodings are longer and some i16 instructions are slow. + virtual bool isTypeDesirableForOp(unsigned Opc, EVT VT) const { + // By default, assume all legal types are desirable. + return isTypeLegal(VT); + } + + /// IsDesirableToPromoteOp - This method query the target whether it is + /// beneficial for dag combiner to promote the specified node. If true, it + /// should return the desired promotion type by reference. + virtual bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const { + return false; + } //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by @@ -950,10 +975,12 @@ protected: /// addRegisterClass - Add the specified register class as an available /// regclass for the specified value type. This indicates the selector can /// handle values of that class natively. - void addRegisterClass(EVT VT, TargetRegisterClass *RC) { + void addRegisterClass(EVT VT, TargetRegisterClass *RC, + bool isSynthesizable = true) { assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT)); AvailableRegClasses.push_back(std::make_pair(VT, RC)); RegClassForVT[VT.getSimpleVT().SimpleTy] = RC; + Synthesizable[VT.getSimpleVT().SimpleTy] = isSynthesizable; } /// computeRegisterProperties - Once all of the register classes are added, @@ -1077,7 +1104,7 @@ protected: public: - virtual const TargetSubtarget *getSubtarget() { + virtual const TargetSubtarget *getSubtarget() const { assert(0 && "Not Implemented"); return NULL; // this is here to silence compiler errors } @@ -1098,7 +1125,7 @@ public: CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) { + SmallVectorImpl<SDValue> &InVals) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1128,7 +1155,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) const; /// LowerCall - This hook must be implemented to lower calls into the /// the specified DAG. The outgoing arguments to the call are described @@ -1142,7 +1169,7 @@ public: const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) { + SmallVectorImpl<SDValue> &InVals) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1154,11 +1181,12 @@ public: virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<EVT> &OutTys, const SmallVectorImpl<ISD::ArgFlagsTy> &ArgsFlags, - SelectionDAG &DAG) + SelectionDAG &DAG) const { // Return true by default to get preexisting behavior. return true; } + /// LowerReturn - This hook must be implemented to lower outgoing /// return values, described by the Outs array, into the specified /// DAG. The implementation should return the resulting token chain @@ -1167,7 +1195,7 @@ public: virtual SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, - DebugLoc dl, SelectionDAG &DAG) { + DebugLoc dl, SelectionDAG &DAG) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1192,7 +1220,7 @@ public: SDValue Op3, unsigned Align, bool isVolatile, bool AlwaysInline, const Value *DstSV, uint64_t DstOff, - const Value *SrcSV, uint64_t SrcOff) { + const Value *SrcSV, uint64_t SrcOff) const { return SDValue(); } @@ -1208,7 +1236,7 @@ public: SDValue Op1, SDValue Op2, SDValue Op3, unsigned Align, bool isVolatile, const Value *DstSV, uint64_t DstOff, - const Value *SrcSV, uint64_t SrcOff) { + const Value *SrcSV, uint64_t SrcOff) const { return SDValue(); } @@ -1223,7 +1251,7 @@ public: SDValue Chain, SDValue Op1, SDValue Op2, SDValue Op3, unsigned Align, bool isVolatile, - const Value *DstSV, uint64_t DstOff) { + const Value *DstSV, uint64_t DstOff) const { return SDValue(); } @@ -1241,14 +1269,14 @@ public: /// The default implementation calls LowerOperation. virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG); + SelectionDAG &DAG) const; /// LowerOperation - This callback is invoked for operations that are /// unsupported by the target, which are registered to use 'custom' lowering, /// and whose defined values are all legal. /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation of this aborts. - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; /// ReplaceNodeResults - This callback is invoked when a node result type is /// illegal for the target, and the operation was registered to use 'custom' @@ -1260,7 +1288,7 @@ public: /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation aborts. virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG) { + SelectionDAG &DAG) const { assert(0 && "ReplaceNodeResults not implemented for this target!"); } @@ -1274,11 +1302,12 @@ public: createFastISel(MachineFunction &, DenseMap<const Value *, unsigned> &, DenseMap<const BasicBlock *, MachineBasicBlock *> &, - DenseMap<const AllocaInst *, int> & + DenseMap<const AllocaInst *, int> &, + std::vector<std::pair<MachineInstr*, unsigned> > & #ifndef NDEBUG - , SmallSet<Instruction*, 8> &CatchInfoLost + , SmallSet<const Instruction *, 8> &CatchInfoLost #endif - ) { + ) const { return 0; } @@ -1398,12 +1427,8 @@ public: // insert. The specified MachineInstr is created but not inserted into any // basic blocks, and this method is called to expand it into a sequence of // instructions, potentially also creating new basic blocks and control flow. - // When new basic blocks are inserted and the edges from MBB to its successors - // are modified, the method should insert pairs of <OldSucc, NewSucc> into the - // DenseMap. - virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *MBB, - DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const; + virtual MachineBasicBlock * + EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). @@ -1524,9 +1549,9 @@ public: } private: - TargetMachine &TM; + const TargetMachine &TM; const TargetData *TD; - TargetLoweringObjectFile &TLOF; + const TargetLoweringObjectFile &TLOF; /// PointerTy - The type to use for pointers, usually i32 or i64. /// @@ -1611,6 +1636,11 @@ private: unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE]; EVT RegisterTypeForVT[MVT::LAST_VALUETYPE]; + /// Synthesizable indicates whether it is OK for the compiler to create new + /// operations using this type. All Legal types are Synthesizable except + /// MMX types on X86. Non-Legal types are not Synthesizable. + bool Synthesizable[MVT::LAST_VALUETYPE]; + /// TransformToType - For any value types we are promoting or expanding, this /// contains the value type that we are changing to. For Expanded types, this /// contains one step of the expand (e.g. i64 -> i32), even if there are diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index d1d665f..c734cf4 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -28,6 +28,7 @@ class TargetInstrInfo; class TargetIntrinsicInfo; class TargetJITInfo; class TargetLowering; +class TargetSelectionDAGInfo; class TargetFrameInfo; class JITCodeEmitter; class MCContext; @@ -105,7 +106,8 @@ public: // virtual const TargetInstrInfo *getInstrInfo() const { return 0; } virtual const TargetFrameInfo *getFrameInfo() const { return 0; } - virtual TargetLowering *getTargetLowering() const { return 0; } + virtual const TargetLowering *getTargetLowering() const { return 0; } + virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; } virtual const TargetData *getTargetData() const { return 0; } /// getMCAsmInfo - Return target specific asm information. @@ -171,6 +173,21 @@ public: /// is false. static void setAsmVerbosityDefault(bool); + /// getDataSections - Return true if data objects should be emitted into their + /// own section, corresponds to -fdata-sections. + static bool getDataSections(); + + /// getFunctionSections - Return true if functions should be emitted into + /// their own section, corresponding to -ffunction-sections. + static bool getFunctionSections(); + + /// setDataSections - Set if the data are emit into separate sections. + static void setDataSections(bool); + + /// setFunctionSections - Set if the functions are emit into separate + /// sections. + static void setFunctionSections(bool); + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit, and returned by /// it to indicate what type of file could actually be made. diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 48665b7..c4deaa8 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -62,9 +62,17 @@ namespace TargetOpcode { /// instructions are insufficient. The actual MachineInstrs to perform /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. COPY_TO_REGCLASS = 10, - + /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic - DBG_VALUE = 11 + DBG_VALUE = 11, + + /// REG_SEQUENCE - This variadic instruction is used to form a register that + /// represent a consecutive sequence of sub-registers. It's used as register + /// coalescing / allocation aid and must be eliminated before code emission. + /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 + /// After register coalescing references of v1024 should be replace with + /// v1027:3, v1025 with v1027:4, etc. + REG_SEQUENCE = 12 }; } // end namespace TargetOpcode } // end namespace llvm diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index a01a67f..a316c70 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -16,6 +16,8 @@ #define LLVM_TARGET_TARGETOPTIONS_H namespace llvm { + class MachineFunction; + // Possible float ABI settings. Used with FloatABIType in TargetOptions.h. namespace FloatABI { enum ABIType { @@ -35,6 +37,16 @@ namespace llvm { /// elimination optimization, this option should disable it. extern bool NoFramePointerElim; + /// NoFramePointerElimNonLeaf - This flag is enabled when the + /// -disable-non-leaf-fp-elim is specified on the command line. If the target + /// supports the frame pointer elimination optimization, this option should + /// disable it for non-leaf functions. + extern bool NoFramePointerElimNonLeaf; + + /// DisableFramePointerElim - This returns true if frame pointer elimination + /// optimization should be disabled for the given machine function. + extern bool DisableFramePointerElim(const MachineFunction &MF); + /// LessPreciseFPMAD - This flag is enabled when the /// -enable-fp-mad is specified on the command line. When this flag is off /// (the default), the code generator is not allowed to generate mad @@ -95,13 +107,9 @@ namespace llvm { /// crt*.o compiling). extern bool NoZerosInBSS; - /// DwarfExceptionHandling - This flag indicates that Dwarf exception - /// information should be emitted. - extern bool DwarfExceptionHandling; - - /// SjLjExceptionHandling - This flag indicates that SJLJ exception - /// information should be emitted. - extern bool SjLjExceptionHandling; + /// JITExceptionHandling - This flag indicates that the JIT should emit + /// exception handling information. + extern bool JITExceptionHandling; /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit /// debug information and notify a debugger about it. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index c197445..29b862a 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -109,7 +109,7 @@ public: } /// contains - Return true if the specified register is included in this - /// register class. + /// register class. This does not include virtual registers. bool contains(unsigned Reg) const { return RegSet.count(Reg); } diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index dcc0992..96c8367 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -22,6 +22,13 @@ // class FuncUnit; +class ReservationKind<bits<1> val> { + int Value = val; +} + +def Required : ReservationKind<0>; +def Reserved : ReservationKind<1>; + //===----------------------------------------------------------------------===// // Instruction stage - These values represent a non-pipelined step in // the execution of an instruction. Cycles represents the number of @@ -36,10 +43,14 @@ class FuncUnit; // InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles // InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit // -class InstrStage<int cycles, list<FuncUnit> units, int timeinc = -1> { + +class InstrStage<int cycles, list<FuncUnit> units, + int timeinc = -1, + ReservationKind kind = Required> { int Cycles = cycles; // length of stage in machine cycles list<FuncUnit> Units = units; // choice of functional units int TimeInc = timeinc; // cycles till start of next stage + int Kind = kind.Value; // kind of FU reservation } //===----------------------------------------------------------------------===// @@ -73,11 +84,12 @@ class InstrItinData<InstrItinClass Class, list<InstrStage> stages, // Processor itineraries - These values represent the set of all itinerary // classes for a given chip set. // -class ProcessorItineraries<list<InstrItinData> iid> { +class ProcessorItineraries<list<FuncUnit> fu, list<InstrItinData> iid> { + list<FuncUnit> FU = fu; list<InstrItinData> IID = iid; } // NoItineraries - A marker that can be used by processors without schedule // info. -def NoItineraries : ProcessorItineraries<[]>; +def NoItineraries : ProcessorItineraries<[], []>; diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h new file mode 100644 index 0000000..943bdea --- /dev/null +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -0,0 +1,36 @@ +//==-- llvm/Target/TargetSelectionDAGInfo.h - SelectionDAG Info --*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the TargetSelectionDAGInfo class, which targets can +// subclass to parameterize the SelectionDAG lowering and instruction +// selection process. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H +#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// TargetSelectionDAGLowering - Targets can subclass this to parameterize the +/// SelectionDAG lowering and instruction selection process. +/// +class TargetSelectionDAGInfo { + TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT + void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT + +public: + TargetSelectionDAGInfo(); + virtual ~TargetSelectionDAGInfo(); +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index c5be59a..6af7ed7 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -40,7 +40,7 @@ struct Inliner : public CallGraphSCCPass { // Main run interface method, this implements the interface required by the // Pass class. - virtual bool runOnSCC(std::vector<CallGraphNode *> &SCC); + virtual bool runOnSCC(CallGraphSCC &SCC); // doFinalization - Remove now-dead linkonce functions at the end of // processing to avoid breaking the SCC traversal. @@ -77,7 +77,7 @@ struct Inliner : public CallGraphSCCPass { /// growCachedCostInfo - update the cached cost info for Caller after Callee /// has been inlined. - virtual void growCachedCostInfo(Function* Caller, Function* Callee) = 0; + virtual void growCachedCostInfo(Function *Caller, Function *Callee) = 0; /// removeDeadFunctions - Remove dead functions that are not included in /// DNR (Do Not Remove) list. diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 6893bad..a8c9c6a 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -241,6 +241,8 @@ extern const PassInfo *const LowerSwitchID; // lowering pass. // FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0); +FunctionPass *createLowerInvokePass(const TargetLowering *TLI, + bool useExpensiveEHSupport); extern const PassInfo *const LowerInvokePassID; //===----------------------------------------------------------------------===// @@ -326,12 +328,6 @@ FunctionPass *createGEPSplitterPass(); //===----------------------------------------------------------------------===// // -// SCCVN - Aggressively eliminate redundant scalar values -// -FunctionPass *createSCCVNPass(); - -//===----------------------------------------------------------------------===// -// // ABCD - Elimination of Array Bounds Checks on Demand // FunctionPass *createABCDPass(); diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h index 8e76f50..6df3469 100644 --- a/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -42,7 +42,7 @@ namespace llvm { /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the /// specified pointer arguments and length. Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetData *TD); + const TargetData *TD, StringRef Name = "strncpy"); /// EmitMemCpy - Emit a call to the memcpy function to the builder. This /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 5f494fb..22bdc99 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -19,7 +19,9 @@ #define LLVM_TRANSFORMS_UTILS_CLONING_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { @@ -40,7 +42,6 @@ class TargetData; class Loop; class LoopInfo; class AllocaInst; -template <typename T> class SmallVectorImpl; /// CloneModule - Return an exact copy of the specified module /// @@ -158,6 +159,33 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, const TargetData *TD = 0, Instruction *TheCall = 0); + +/// InlineFunctionInfo - This class captures the data input to the +/// InlineFunction call, and records the auxiliary results produced by it. +class InlineFunctionInfo { +public: + explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *td = 0) + : CG(cg), TD(td) {} + + /// CG - If non-null, InlineFunction will update the callgraph to reflect the + /// changes it makes. + CallGraph *CG; + const TargetData *TD; + + /// StaticAllocas - InlineFunction fills this in with all static allocas that + /// get copied into the caller. + SmallVector<AllocaInst*, 4> StaticAllocas; + + /// InlinedCalls - InlineFunction fills this in with callsites that were + /// inlined from the callee. This is only filled in if CG is non-null. + SmallVector<WeakVH, 8> InlinedCalls; + + void reset() { + StaticAllocas.clear(); + InlinedCalls.clear(); + } +}; + /// InlineFunction - This function inlines the called function into the basic /// block of the caller. This returns false if it is not possible to inline /// this call. The program is still in a well defined state if this occurs @@ -168,18 +196,9 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, /// exists in the instruction stream. Similiarly this will inline a recursive /// function by one level. /// -/// If a non-null callgraph pointer is provided, these functions update the -/// CallGraph to represent the program after inlining. -/// -/// If StaticAllocas is non-null, InlineFunction populates it with all of the -/// static allocas that it inlines into the caller. -/// -bool InlineFunction(CallInst *C, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl<AllocaInst*> *StaticAllocas = 0); -bool InlineFunction(InvokeInst *II, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl<AllocaInst*> *StaticAllocas = 0); -bool InlineFunction(CallSite CS, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl<AllocaInst*> *StaticAllocas = 0); +bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI); +bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI); +bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI); } // End llvm namespace diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 927e156..5b77ed6 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -21,28 +21,31 @@ namespace llvm { class PHINode; template<typename T> class SmallVectorImpl; + class BumpPtrAllocator; /// SSAUpdater - This class updates SSA form for a set of values defined in /// multiple blocks. This is used when code duplication or another unstructured /// transformation wants to rewrite a set of uses of one value with uses of a /// set of values. class SSAUpdater { +public: + class BBInfo; + typedef SmallVectorImpl<BBInfo*> BlockListTy; + +private: /// 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 - /// 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; + /// basis. When we insert PHI nodes, we keep track of them here. + //typedef DenseMap<BasicBlock*, Value*> AvailableValsTy; void *AV; /// PrototypeValue is an arbitrary representative value, which we derive names /// and a type for PHI nodes. Value *PrototypeValue; - /// IncomingPredInfo - We use this as scratch space when doing our recursive - /// walk. This should only be used in GetValueInBlockInternal, normally it - /// should be empty. - //std::vector<std::pair<BasicBlock*, TrackingVH<Value> > > IncomingPredInfo; - void *IPI; + /// BBMap - The GetValueAtEndOfBlock method maintains this mapping from + /// basic blocks to BBInfo structures. + /// typedef DenseMap<BasicBlock*, BBInfo*> BBMapTy; + void *BM; /// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that /// it creates to the vector. @@ -99,6 +102,15 @@ public: private: Value *GetValueAtEndOfBlockInternal(BasicBlock *BB); + void BuildBlockList(BasicBlock *BB, BlockListTy *BlockList, + BumpPtrAllocator *Allocator); + void FindDominators(BlockListTy *BlockList); + void FindPHIPlacement(BlockListTy *BlockList); + void FindAvailableVals(BlockListTy *BlockList); + void FindExistingPHI(BasicBlock *BB, BlockListTy *BlockList); + bool CheckIfPHIMatches(PHINode *PHI); + void RecordMatchingPHI(PHINode *PHI); + void operator=(const SSAUpdater&); // DO NOT IMPLEMENT SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT }; diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h deleted file mode 100644 index ed33413..0000000 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ /dev/null @@ -1,29 +0,0 @@ -//===- ValueMapper.h - Interface shared by lib/Transforms/Utils -*- 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 MapValue interface which is used by various parts of -// the Transforms/Utils library to implement cloning and linking facilities. -// -//===----------------------------------------------------------------------===// - -#ifndef VALUEMAPPER_H -#define VALUEMAPPER_H - -#include "llvm/ADT/DenseMap.h" - -namespace llvm { - class Value; - class Instruction; - typedef DenseMap<const Value *, Value *> ValueMapTy; - - Value *MapValue(const Value *V, ValueMapTy &VM); - void RemapInstruction(Instruction *I, ValueMapTy &VM); -} // End llvm namespace - -#endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index df3a16c..52229ac 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -406,6 +406,7 @@ public: static const Type *getX86_FP80Ty(LLVMContext &C); static const Type *getFP128Ty(LLVMContext &C); static const Type *getPPC_FP128Ty(LLVMContext &C); + static const IntegerType *getIntNTy(LLVMContext &C, unsigned N); static const IntegerType *getInt1Ty(LLVMContext &C); static const IntegerType *getInt8Ty(LLVMContext &C); static const IntegerType *getInt16Ty(LLVMContext &C); @@ -421,6 +422,8 @@ public: static const PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); static const PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); static const PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); + static const PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, + unsigned AS = 0); static const PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); static const PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); static const PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); |