diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-05-04 16:11:02 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-05-04 16:11:02 +0000 |
commit | 750ce4d809c7e2a298a389a512a17652ff5be3f2 (patch) | |
tree | 70fbd90da02177c8e6ef82adba9fa8ace285a5e3 /include | |
parent | 5f970ec96e421f64db6b1c6509a902ea73d98cc7 (diff) | |
download | FreeBSD-src-750ce4d809c7e2a298a389a512a17652ff5be3f2.zip FreeBSD-src-750ce4d809c7e2a298a389a512a17652ff5be3f2.tar.gz |
Update LLVM to r103004.
Diffstat (limited to 'include')
99 files changed, 2400 insertions, 1474 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 733b92c..d665c89 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -319,6 +319,8 @@ LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name); /** See Module::dump. */ void LLVMDumpModule(LLVMModuleRef M); +/** See Module::setModuleInlineAsm. */ +void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm); /*===-- Types -------------------------------------------------------------===*/ diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h index 9cd1e1f..ebb2cf8 100644 --- a/include/llvm-c/EnhancedDisassembly.h +++ b/include/llvm-c/EnhancedDisassembly.h @@ -55,7 +55,8 @@ typedef enum { /*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */ kEDAssemblySyntaxX86Intel = 0, /*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */ - kEDAssemblySyntaxX86ATT = 1 + kEDAssemblySyntaxX86ATT = 1, + kEDAssemblySyntaxARMUAL = 2 } EDAssemblySyntax_t; /*! diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index e705a99..2948fc7 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -32,18 +32,18 @@ typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; typedef struct LLVMStructLayout *LLVMStructLayoutRef; /* Declare all of the target-initialization functions that are available. */ -#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo(); +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo(void); #include "llvm/Config/Targets.def" #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ -#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(void); #include "llvm/Config/Targets.def" #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ /** LLVMInitializeAllTargetInfos - The main program should call this function if it wants access to all available targets that LLVM is configured to support. */ -static inline void LLVMInitializeAllTargetInfos() { +static inline void LLVMInitializeAllTargetInfos(void) { #define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo(); #include "llvm/Config/Targets.def" #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ @@ -52,7 +52,7 @@ static inline void LLVMInitializeAllTargetInfos() { /** LLVMInitializeAllTargets - The main program should call this function if it wants to link in all available targets that LLVM is configured to support. */ -static inline void LLVMInitializeAllTargets() { +static inline void LLVMInitializeAllTargets(void) { #define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ @@ -61,7 +61,7 @@ static inline void LLVMInitializeAllTargets() { /** LLVMInitializeNativeTarget - The main program should call this function to initialize the native target corresponding to the host. This is useful for JIT applications to ensure that the target gets linked in correctly. */ -static inline LLVMBool LLVMInitializeNativeTarget() { +static inline LLVMBool LLVMInitializeNativeTarget(void) { /* If we have a native target, initialize it to ensure it is linked in. */ #ifdef LLVM_NATIVE_ARCH #define DoInit2(TARG) \ diff --git a/include/llvm-c/Transforms/IPO.h b/include/llvm-c/Transforms/IPO.h index 0a94315..d16e858 100644 --- a/include/llvm-c/Transforms/IPO.h +++ b/include/llvm-c/Transforms/IPO.h @@ -54,6 +54,12 @@ void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM); /** See llvm::createPruneEHPass function. */ void LLVMAddPruneEHPass(LLVMPassManagerRef PM); +/** See llvm::createIPSCCPPass function. */ +void LLVMAddIPSCCPPass(LLVMPassManagerRef PM); + +/** See llvm::createInternalizePass function. */ +void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain); + // FIXME: Remove in LLVM 3.0. void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM); 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); |