diff options
Diffstat (limited to 'include/llvm')
48 files changed, 1029 insertions, 428 deletions
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 9c046ef..45108c8 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -95,6 +95,9 @@ public: delete[] Bits; } + /// empty - Tests whether there are no bits in this bitvector. + bool empty() const { return Size == 0; } + /// size - Returns the number of bits in this bitvector. unsigned size() const { return Size; } @@ -341,6 +344,12 @@ public: return *this; } + void swap(BitVector &RHS) { + std::swap(Bits, RHS.Bits); + std::swap(Size, RHS.Size); + std::swap(Capacity, RHS.Capacity); + } + private: unsigned NumBitWords(unsigned S) const { return (S + BITWORD_SIZE-1) / BITWORD_SIZE; @@ -406,4 +415,13 @@ inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) { } } // End llvm namespace + +namespace std { + /// Implement std::swap in terms of BitVector swap. + inline void + swap(llvm::BitVector &LHS, llvm::BitVector &RHS) { + LHS.swap(RHS); + } +} + #endif diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h new file mode 100644 index 0000000..346fb1c --- /dev/null +++ b/include/llvm/ADT/SmallBitVector.h @@ -0,0 +1,373 @@ +//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the SmallBitVector class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_SMALLBITVECTOR_H +#define LLVM_ADT_SMALLBITVECTOR_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm { + +/// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array), +/// optimized for the case when the array is small. It contains one +/// pointer-sized field, which is directly used as a plain collection of bits +/// when possible, or as a pointer to a larger heap-allocated array when +/// necessary. This allows normal "small" cases to be fast without losing +/// generality for large inputs. +/// +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; + + // The number of bits in this class. + static const size_t 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; + + // 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); + + // The remaining bits are used to store the actual set in small mode. + static const size_t SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits; + + bool isSmall() const { + return X.getInt(); + } + + void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) { + X.setInt(true); + setSmallSize(NewSize); + setSmallBits(NewSmallBits); + } + + void switchToLarge(BitVector *BV) { + X.setInt(false); + X.setPointer(BV); + } + + // 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; + } + + void setSmallRawBits(uintptr_t NewRawBits) { + return X.setPointer(reinterpret_cast<BitVector *>(NewRawBits << 1)); + } + + // Return the size. + size_t getSmallSize() const { + return getSmallRawBits() >> SmallNumDataBits; + } + + void setSmallSize(size_t Size) { + setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); + } + + // Return the element bits. + uintptr_t getSmallBits() const { + return getSmallRawBits() & ~(~uintptr_t(0) << SmallNumDataBits); + } + + void setSmallBits(uintptr_t NewBits) { + setSmallRawBits((getSmallRawBits() & (~uintptr_t(0) << SmallNumDataBits)) | + (NewBits & ~(~uintptr_t(0) << getSmallSize()))); + } + +public: + /// SmallBitVector default ctor - Creates an empty bitvector. + SmallBitVector() : X(0, 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) + switchToSmall(t ? ~uintptr_t(0) : 0, s); + else + switchToLarge(new BitVector(s, t)); + } + + /// SmallBitVector copy ctor. + SmallBitVector(const SmallBitVector &RHS) { + if (RHS.isSmall()) + X = RHS.X; + else + switchToLarge(new BitVector(*RHS.X.getPointer())); + } + + ~SmallBitVector() { + if (!isSmall()) + delete X.getPointer(); + } + + /// empty - Tests whether there are no bits in this bitvector. + bool empty() const { + return isSmall() ? getSmallSize() == 0 : X.getPointer()->empty(); + } + + /// size - Returns the number of bits in this bitvector. + size_t size() const { + return isSmall() ? getSmallSize() : X.getPointer()->size(); + } + + /// count - Returns the number of bits which are set. + unsigned count() const { + if (isSmall()) { + uintptr_t Bits = getSmallBits(); + if (sizeof(uintptr_t) * CHAR_BIT == 32) + return CountPopulation_32(Bits); + if (sizeof(uintptr_t) * CHAR_BIT == 64) + return CountPopulation_64(Bits); + assert(0 && "Unsupported!"); + } + return X.getPointer()->count(); + } + + /// any - Returns true if any bit is set. + bool any() const { + if (isSmall()) + return getSmallBits() != 0; + return X.getPointer()->any(); + } + + /// none - Returns true if none of the bits are set. + bool none() const { + if (isSmall()) + return getSmallBits() == 0; + return X.getPointer()->none(); + } + + /// find_first - Returns the index of the first set bit, -1 if none + /// of the bits are set. + int find_first() const { + if (isSmall()) { + uintptr_t Bits = getSmallBits(); + 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(); + } + + /// find_next - Returns the index of the next set bit following the + /// "Prev" bit. Returns -1 if the next set bit is not found. + int find_next(unsigned Prev) const { + if (isSmall()) { + uintptr_t Bits = getSmallBits(); + // Mask off previous bits. + Bits &= ~uintptr_t(0) << Prev; + 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); + } + + /// clear - Clear all bits. + void clear() { + if (!isSmall()) + delete X.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) { + setSmallSize(N); + setSmallBits(getSmallBits()); + } else { + BitVector *BV = new BitVector(N, t); + uintptr_t OldBits = getSmallBits(); + for (size_t i = 0, e = getSmallSize(); i != e; ++i) + (*BV)[i] = (OldBits >> i) & 1; + switchToLarge(BV); + } + } + + void reserve(unsigned N) { + if (isSmall()) { + if (N > SmallNumDataBits) { + uintptr_t OldBits = getSmallRawBits(); + size_t SmallSize = getSmallSize(); + BitVector *BV = new BitVector(SmallSize); + for (size_t i = 0; i < SmallSize; ++i) + if ((OldBits >> i) & 1) + BV->set(i); + BV->reserve(N); + switchToLarge(BV); + } + } else { + X.getPointer()->reserve(N); + } + } + + // Set, reset, flip + SmallBitVector &set() { + if (isSmall()) + setSmallBits(~uintptr_t(0)); + else + X.getPointer()->set(); + return *this; + } + + SmallBitVector &set(unsigned Idx) { + if (isSmall()) + setSmallBits(getSmallBits() | (uintptr_t(1) << Idx)); + else + X.getPointer()->set(Idx); + return *this; + } + + SmallBitVector &reset() { + if (isSmall()) + setSmallBits(0); + else + X.getPointer()->reset(); + return *this; + } + + SmallBitVector &reset(unsigned Idx) { + if (isSmall()) + setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); + else + X.getPointer()->reset(Idx); + return *this; + } + + SmallBitVector &flip() { + if (isSmall()) + setSmallBits(~getSmallBits()); + else + X.getPointer()->flip(); + return *this; + } + + SmallBitVector &flip(unsigned Idx) { + if (isSmall()) + setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); + else + X.getPointer()->flip(Idx); + return *this; + } + + // No argument flip. + SmallBitVector operator~() const { + return SmallBitVector(*this).flip(); + } + + // Indexing. + // TODO: Add an index operator which returns a "reference" (proxy class). + 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); + } + + bool test(unsigned Idx) const { + return (*this)[Idx]; + } + + // Comparison operators. + bool operator==(const SmallBitVector &RHS) const { + if (size() != RHS.size()) + return false; + if (isSmall()) + return getSmallBits() == RHS.getSmallBits(); + else + return *X.getPointer() == *RHS.X.getPointer(); + } + + bool operator!=(const SmallBitVector &RHS) const { + return !(*this == RHS); + } + + // Intersection, union, disjoint union. + BitVector &operator&=(const SmallBitVector &RHS); // TODO: implement + + BitVector &operator|=(const SmallBitVector &RHS); // TODO: implement + + BitVector &operator^=(const SmallBitVector &RHS); // TODO: implement + + // Assignment operator. + const SmallBitVector &operator=(const SmallBitVector &RHS) { + if (isSmall()) { + if (RHS.isSmall()) + X = RHS.X; + else + switchToLarge(new BitVector(*RHS.X.getPointer())); + } else { + if (!RHS.isSmall()) + *X.getPointer() = *RHS.X.getPointer(); + else { + delete X.getPointer(); + X = RHS.X; + } + } + return *this; + } + + void swap(SmallBitVector &RHS) { + std::swap(X, RHS.X); + } +}; + +inline SmallBitVector +operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) { + SmallBitVector Result(LHS); + Result &= RHS; + return Result; +} + +inline SmallBitVector +operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) { + SmallBitVector Result(LHS); + Result |= RHS; + return Result; +} + +inline SmallBitVector +operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { + SmallBitVector Result(LHS); + Result ^= RHS; + return Result; +} + +} // End llvm namespace + +namespace std { + /// Implement std::swap in terms of BitVector swap. + inline void + swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { + LHS.swap(RHS); + } +} + +#endif diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 85936c0..1ea546f 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -23,6 +23,7 @@ #include <vector> namespace llvm { +template<typename T> class SmallVectorImpl; /// hexdigit - Return the (uppercase) hexadecimal character for the /// given number \arg X (which should be less than 16). @@ -136,86 +137,25 @@ static inline std::string UppercaseString(const std::string &S) { return result; } -/// StringsEqualNoCase - Return true if the two strings are equal, ignoring -/// case. -static inline bool StringsEqualNoCase(const std::string &LHS, - const std::string &RHS) { - if (LHS.size() != RHS.size()) return false; - for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) - if (tolower(LHS[i]) != tolower(RHS[i])) return false; - return true; -} - -/// StringsEqualNoCase - Return true if the two strings are equal, ignoring -/// case. -static inline bool StringsEqualNoCase(const std::string &LHS, - const char *RHS) { - for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) { - if (RHS[i] == 0) return false; // RHS too short. - if (tolower(LHS[i]) != tolower(RHS[i])) return false; - } - return RHS[LHS.size()] == 0; // Not too long? -} - -/// StringsEqualNoCase - Return true if the two null-terminated C strings are -/// equal, ignoring - -static inline bool StringsEqualNoCase(const char *LHS, const char *RHS, - unsigned len) { - - for (unsigned i = 0; i < len; ++i) { - if (tolower(LHS[i]) != tolower(RHS[i])) - return false; - - // If RHS[i] == 0 then LHS[i] == 0 or otherwise we would have returned - // at the previous branch as tolower('\0') == '\0'. - if (RHS[i] == 0) - return true; - } - - return true; -} - -/// CStrInCStrNoCase - Portable version of strcasestr. Locates the first -/// occurance of c-string 's2' in string 's1', ignoring case. Returns -/// NULL if 's2' cannot be found. -static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) { - - // Are either strings NULL or empty? - if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0') - return 0; - - if (s1 == s2) - return s1; - - const char *I1=s1, *I2=s2; - - while (*I1 != '\0' && *I2 != '\0' ) - if (tolower(*I1) != tolower(*I2)) { // No match. Start over. - ++s1; I1 = s1; I2 = s2; - } - else { // Character match. Advance to the next character. - ++I1; ++I2; - } - - // If we exhausted all of the characters in 's2', then 's2' appears in 's1'. - return *I2 == '\0' ? s1 : 0; -} +/// StrInStrNoCase - Portable version of strcasestr. Locates the first +/// occurrence of string 's1' in string 's2', ignoring case. Returns +/// the offset of s2 in s1 or npos if s2 cannot be found. +StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2); /// getToken - This function extracts one token from source, ignoring any /// leading characters that appear in the Delimiters string, and ending the /// token at any of the characters that appear in the Delimiters string. If /// there are no tokens in the source string, an empty string is returned. -/// The Source source string is updated in place to remove the returned string -/// and any delimiter prefix from it. -std::string getToken(std::string &Source, - const char *Delimiters = " \t\n\v\f\r"); +/// The function returns a pair containing the extracted token and the +/// remaining tail string. +std::pair<StringRef, StringRef> getToken(StringRef Source, + StringRef Delimiters = " \t\n\v\f\r"); /// SplitString - Split up the specified string according to the specified /// delimiters, appending the result fragments to the output list. -void SplitString(const std::string &Source, - std::vector<std::string> &OutFragments, - const char *Delimiters = " \t\n\v\f\r"); +void SplitString(StringRef Source, + SmallVectorImpl<StringRef> &OutFragments, + StringRef Delimiters = " \t\n\v\f\r"); /// HashString - Hash funtion for strings. /// diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 1c73836..3064af3 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -29,6 +29,7 @@ namespace llvm { class StringRef { public: typedef const char *iterator; + typedef const char *const_iterator; static const size_t npos = ~size_t(0); typedef size_t size_type; @@ -42,15 +43,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; - } + 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; } public: /// @name Constructors @@ -191,7 +185,7 @@ namespace llvm { /// find - Search for the first character \arg C in the string. /// - /// \return - The index of the first occurence of \arg C, or npos if not + /// \return - The index of the first occurrence of \arg C, or npos if not /// found. size_t find(char C, size_t From = 0) const { for (size_t i = min(From, Length), e = Length; i != e; ++i) @@ -202,13 +196,13 @@ namespace llvm { /// find - Search for the first string \arg Str in the string. /// - /// \return - The index of the first occurence of \arg Str, or npos if not + /// \return - The index of the first occurrence of \arg Str, or npos if not /// found. size_t find(StringRef Str, size_t From = 0) const; /// rfind - Search for the last character \arg C in the string. /// - /// \return - The index of the last occurence of \arg C, or npos if not + /// \return - The index of the last occurrence of \arg C, or npos if not /// found. size_t rfind(char C, size_t From = npos) const { From = min(From, Length); @@ -223,7 +217,7 @@ namespace llvm { /// rfind - Search for the last string \arg Str in the string. /// - /// \return - The index of the last occurence of \arg Str, or npos if not + /// \return - The index of the last occurrence of \arg Str, or npos if not /// found. size_t rfind(StringRef Str) const; @@ -313,7 +307,7 @@ namespace llvm { return StringRef(Data + Start, End - Start); } - /// split - Split into two substrings around the first occurence of a + /// split - Split into two substrings around the first occurrence of a /// separator character. /// /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) @@ -330,7 +324,7 @@ namespace llvm { return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); } - /// split - Split into two substrings around the first occurence of a + /// split - Split into two substrings around the first occurrence of a /// separator string. /// /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) @@ -347,7 +341,7 @@ namespace llvm { return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); } - /// split - Split into substrings around the occurences of a separator + /// split - Split into substrings around the occurrences of a separator /// string. /// /// Each substring is stored in \arg A. If \arg MaxSplit is >= 0, at most @@ -366,7 +360,7 @@ namespace llvm { StringRef Separator, int MaxSplit = -1, bool KeepEmpty = true) const; - /// rsplit - Split into two substrings around the last occurence of a + /// rsplit - Split into two substrings around the last occurrence of a /// separator character. /// /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index ca0be53..97e9df4 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -329,6 +329,22 @@ namespace llvm { bool isTriviallyEmpty() const { return isNullary(); } + + /// isSingleStringRef - Return true if this twine can be dynamically + /// accessed as a single StringRef value with getSingleStringRef(). + bool isSingleStringRef() const { + if (getRHSKind() != EmptyKind) return false; + + switch (getLHSKind()) { + case EmptyKind: + case CStringKind: + case StdStringKind: + case StringRefKind: + return true; + default: + return false; + } + } /// @} /// @name String Operations @@ -347,6 +363,24 @@ namespace llvm { /// SmallVector. void toVector(SmallVectorImpl<char> &Out) const; + /// getSingleStringRef - This returns the twine as a single StringRef. This + /// method is only valid if isSingleStringRef() is true. + StringRef getSingleStringRef() const { + assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); + switch (getLHSKind()) { + default: assert(0 && "Out of sync with isSingleStringRef"); + case EmptyKind: return StringRef(); + case CStringKind: return StringRef((const char*)LHS); + case StdStringKind: return StringRef(*(const std::string*)LHS); + case StringRefKind: return *(const StringRef*)LHS; + } + } + + /// toStringRef - This returns the twine as a single StringRef if it can be + /// represented as such. Otherwise the twine is written into the given + /// SmallVector and a StringRef to the SmallVector's data is returned. + StringRef toStringRef(SmallVectorImpl<char> &Out) const; + /// print - Write the concatenated string represented by this twine to the /// stream \arg OS. void print(raw_ostream &OS) const; diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 2d43bdd..9f41135 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -197,6 +197,10 @@ public: virtual ModRefBehavior getModRefBehavior(Function *F, std::vector<PointerAccessInfo> *Info = 0); + /// getModRefBehavior - Return the modref behavior of the intrinsic with the + /// given id. + static ModRefBehavior getModRefBehavior(unsigned iid); + /// doesNotAccessMemory - If the specified call is known to never read or /// write memory, return true. If the call only reads from known-constant /// memory, it is also legal to return true. Calls that unwind the stack diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index fdbd9c1..cc9514c 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -30,11 +30,7 @@ namespace llvm { class Module; class Type; class Value; - struct DbgStopPointInst; - struct DbgDeclareInst; - struct DbgFuncStartInst; - struct DbgRegionStartInst; - struct DbgRegionEndInst; + class DbgDeclareInst; class DebugLoc; struct DebugLocTracker; class Instruction; @@ -495,7 +491,6 @@ namespace llvm { Module &M; LLVMContext& VMContext; - const Type *EmptyStructPtr; // "{}*". Function *DeclareFn; // llvm.dbg.declare Function *ValueFn; // llvm.dbg.value @@ -651,27 +646,19 @@ namespace llvm { Instruction *InsertBefore); /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset, DIVariable D, BasicBlock *InsertAtEnd); /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset, DIVariable D, Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); }; - /// Finds the stoppoint coressponding to this instruction, that is the - /// stoppoint that dominates this instruction - const DbgStopPointInst *findStopPoint(const Instruction *Inst); - - /// Finds the stoppoint corresponding to first real (non-debug intrinsic) - /// instruction in this Basic Block, and returns the stoppoint for it. - const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB); - /// Finds the dbg.declare intrinsic corresponding to this value if any. /// It looks through pointer casts too. - const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts = true); + const DbgDeclareInst *findDbgDeclare(const Value *V); /// Find the debug info descriptor corresponding to this global variable. Value *findDbgGlobalDeclare(GlobalVariable *V); @@ -681,20 +668,10 @@ namespace llvm { std::string &Dir); /// ExtractDebugLocation - Extract debug location information - /// from llvm.dbg.stoppoint intrinsic. - DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI, - DebugLocTracker &DebugLocInfo); - - /// ExtractDebugLocation - Extract debug location information /// from DILocation. DebugLoc ExtractDebugLocation(DILocation &Loc, DebugLocTracker &DebugLocInfo); - /// ExtractDebugLocation - Extract debug location information - /// from llvm.dbg.func_start intrinsic. - DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI, - DebugLocTracker &DebugLocInfo); - /// getDISubprogram - Find subprogram that is enclosing this scope. DISubprogram getDISubprogram(MDNode *Scope); diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h index cca0d50..5ecb348 100644 --- a/include/llvm/Analysis/DominatorInternals.h +++ b/include/llvm/Analysis/DominatorInternals.h @@ -347,15 +347,8 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, DT.IDoms.clear(); DT.Info.clear(); std::vector<typename GraphT::NodeType*>().swap(DT.Vertex); - - // FIXME: This does not work on PostDomTrees. It seems likely that this is - // due to an error in the algorithm for post-dominators. This really should - // be investigated and fixed at some point. - // DT.updateDFSNumbers(); - - // Start out with the DFS numbers being invalid. Let them be computed if - // demanded. - DT.DFSInfoValid = false; + + DT.updateDFSNumbers(); } } diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 2e149d5..31c19c4 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -390,6 +390,13 @@ public: if (A == 0 || B == 0) return false; + // Compare the result of the tree walk and the dfs numbers, if expensive + // checks are enabled. +#ifdef XDEBUG + assert(!DFSInfoValid + || (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))); +#endif + if (DFSInfoValid) return B->DominatedBy(A); @@ -585,29 +592,35 @@ protected: SmallVector<std::pair<DomTreeNodeBase<NodeT>*, typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack; - for (unsigned i = 0, e = (unsigned)this->Roots.size(); i != e; ++i) { - DomTreeNodeBase<NodeT> *ThisRoot = getNode(this->Roots[i]); - WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); - ThisRoot->DFSNumIn = DFSNum++; - - while (!WorkStack.empty()) { - DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; - typename DomTreeNodeBase<NodeT>::iterator ChildIt = - WorkStack.back().second; - - // If we visited all of the children of this node, "recurse" back up the - // stack setting the DFOutNum. - if (ChildIt == Node->end()) { - Node->DFSNumOut = DFSNum++; - WorkStack.pop_back(); - } else { - // Otherwise, recursively visit this child. - DomTreeNodeBase<NodeT> *Child = *ChildIt; - ++WorkStack.back().second; - - WorkStack.push_back(std::make_pair(Child, Child->begin())); - Child->DFSNumIn = DFSNum++; - } + DomTreeNodeBase<NodeT> *ThisRoot = getRootNode(); + + if (!ThisRoot) + return; + + // Even in the case of multiple exits that form the post dominator root + // nodes, do not iterate over all exits, but start from the virtual root + // node. Otherwise bbs, that are not post dominated by any exit but by the + // virtual root node, will never be assigned a DFS number. + WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); + ThisRoot->DFSNumIn = DFSNum++; + + while (!WorkStack.empty()) { + DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; + typename DomTreeNodeBase<NodeT>::iterator ChildIt = + WorkStack.back().second; + + // If we visited all of the children of this node, "recurse" back up the + // stack setting the DFOutNum. + if (ChildIt == Node->end()) { + Node->DFSNumOut = DFSNum++; + WorkStack.pop_back(); + } else { + // Otherwise, recursively visit this child. + DomTreeNodeBase<NodeT> *Child = *ChildIt; + ++WorkStack.back().second; + + WorkStack.push_back(std::make_pair(Child, Child->begin())); + Child->DFSNumIn = DFSNum++; } } @@ -646,21 +659,17 @@ public: /// recalculate - compute a dominator tree for the given function template<class FT> void recalculate(FT& F) { - if (!this->IsPostDominators) { - reset(); + reset(); + this->Vertex.push_back(0); - // Initialize roots + if (!this->IsPostDominators) { + // Initialize root this->Roots.push_back(&F.front()); this->IDoms[&F.front()] = 0; this->DomTreeNodes[&F.front()] = 0; - this->Vertex.push_back(0); Calculate<FT, NodeT*>(*this, F); - - updateDFSNumbers(); } else { - reset(); // Reset from the last time we were run... - // Initialize the roots list for (typename FT::iterator I = F.begin(), E = F.end(); I != E; ++I) { if (std::distance(GraphTraits<FT*>::child_begin(I), @@ -672,8 +681,6 @@ public: this->DomTreeNodes[I] = 0; } - this->Vertex.push_back(0); - Calculate<FT, Inverse<NodeT*> >(*this, F); } } diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 060286f..33bf0b0 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -478,7 +478,7 @@ public: for (iterator I = begin(), E = end(); I != E; ++I) (*I)->print(OS, Depth+2); } - + protected: friend class LoopInfoBase<BlockT, LoopT>; explicit LoopBase(BlockT *BB) : ParentLoop(0) { @@ -588,6 +588,8 @@ public: /// block, return that block. Otherwise return null. BasicBlock *getUniqueExitBlock() const; + void dump() const; + private: friend class LoopInfoBase<BasicBlock, Loop>; explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {} diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index ea14b2d..3681cc01 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -36,19 +36,23 @@ struct PostDominatorTree : public FunctionPass { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } - + inline const std::vector<BasicBlock*> &getRoots() const { return DT->getRoots(); } - + inline DomTreeNode *getRootNode() const { return DT->getRootNode(); } - + inline DomTreeNode *operator[](BasicBlock *BB) const { return DT->getNode(BB); } - + + inline DomTreeNode *getNode(BasicBlock *BB) const { + return DT->getNode(BB); + } + inline bool dominates(DomTreeNode* A, DomTreeNode* B) const { return DT->dominates(A, B); } @@ -60,7 +64,7 @@ struct PostDominatorTree : public FunctionPass { inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const { return DT->properlyDominates(A, B); } - + inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const { return DT->properlyDominates(A, B); } @@ -97,7 +101,7 @@ template <> struct GraphTraits<PostDominatorTree*> /// struct PostDominanceFrontier : public DominanceFrontierBase { static char ID; - PostDominanceFrontier() + PostDominanceFrontier() : DominanceFrontierBase(&ID, true) {} virtual bool runOnFunction(Function &) { diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 0bbdc34..068f81f 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -1,4 +1,4 @@ -//===-- llvm/Attributes.h - Container for Attributes ---*---------- C++ -*-===// +//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -27,9 +27,9 @@ typedef unsigned Attributes; namespace Attribute { -/// Function parameters and results can have attributes to indicate how they -/// should be treated by optimizations and code generation. This enumeration -/// lists the attributes that can be associated with parameters, function +/// Function parameters and results can have attributes to indicate how they +/// should be treated by optimizations and code generation. This enumeration +/// lists the attributes that can be associated with parameters, function /// results or the function itself. /// @brief Function attributes. @@ -45,7 +45,7 @@ const Attributes ByVal = 1<<7; ///< Pass structure by value const Attributes Nest = 1<<8; ///< Nested function static chain const Attributes ReadNone = 1<<9; ///< Function does not access memory const Attributes ReadOnly = 1<<10; ///< Function only reads from memory -const Attributes NoInline = 1<<11; ///< inline=never +const Attributes NoInline = 1<<11; ///< inline=never const Attributes AlwaysInline = 1<<12; ///< inline=always const Attributes OptimizeForSize = 1<<13; ///< opt_size const Attributes StackProtect = 1<<14; ///< Stack protection. @@ -58,14 +58,15 @@ const Attributes NoRedZone = 1<<22; /// disable redzone const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point /// instructions. const Attributes Naked = 1<<24; ///< Naked function -const Attributes InlineHint = 1<<25; ///< source said inlining was desirable +const Attributes InlineHint = 1<<25; ///< source said inlining was + ///desirable /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// @brief Attributes that may be applied to the function itself. These cannot /// be used on return values or function parameters. -const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | +const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoRedZone | NoImplicitFloat | Naked | InlineHint; @@ -100,26 +101,26 @@ inline unsigned getAlignmentFromAttrs(Attributes A) { Attributes Align = A & Attribute::Alignment; if (Align == 0) return 0; - + return 1U << ((Align >> 16) - 1); } - - + + /// The set of Attributes set in Attributes is converted to a /// string of equivalent mnemonics. This is, presumably, for writing out -/// the mnemonics for the assembly writer. +/// the mnemonics for the assembly writer. /// @brief Convert attribute bits to text std::string getAsString(Attributes Attrs); } // end namespace Attribute /// This is just a pair of values to associate a set of attributes -/// with an index. +/// with an index. struct AttributeWithIndex { Attributes Attrs; ///< The attributes that are set, or'd together. unsigned Index; ///< Index of the parameter for which the attributes apply. ///< Index 0 is used for return value attributes. ///< Index ~0U is used for function attributes. - + static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { AttributeWithIndex P; P.Index = Idx; @@ -127,14 +128,14 @@ struct AttributeWithIndex { return P; } }; - + //===----------------------------------------------------------------------===// // AttrListPtr Smart Pointer //===----------------------------------------------------------------------===// class AttributeListImpl; - -/// AttrListPtr - This class manages the ref count for the opaque + +/// AttrListPtr - This class manages the ref count for the opaque /// AttributeListImpl object and provides accessors for it. class AttrListPtr { /// AttrList - The attributes that we are managing. This can be null @@ -145,14 +146,14 @@ public: AttrListPtr(const AttrListPtr &P); const AttrListPtr &operator=(const AttrListPtr &RHS); ~AttrListPtr(); - + //===--------------------------------------------------------------------===// // Attribute List Construction and Mutation //===--------------------------------------------------------------------===// - + /// get - Return a Attributes list with the specified parameter in it. static AttrListPtr get(const AttributeWithIndex *Attr, unsigned NumAttrs); - + /// get - Return a Attribute list with the parameters specified by the /// consecutive random access iterator range. template <typename Iter> @@ -165,24 +166,24 @@ public: /// attribute list. Since attribute lists are immutable, this /// returns the new list. AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const; - + /// removeAttr - Remove the specified attribute at the specified index from /// this attribute list. Since attribute lists are immutable, this /// returns the new list. AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const; - + //===--------------------------------------------------------------------===// // Attribute List Accessors //===--------------------------------------------------------------------===// /// getParamAttributes - The attributes for the specified index are - /// returned. + /// returned. Attributes getParamAttributes(unsigned Idx) const { assert (Idx && Idx != ~0U && "Invalid parameter index!"); return getAttributes(Idx); } /// getRetAttributes - The attributes for the ret value are - /// returned. + /// returned. Attributes getRetAttributes() const { return getAttributes(0); } @@ -191,58 +192,60 @@ public: Attributes getFnAttributes() const { return getAttributes(~0U); } - + /// paramHasAttr - Return true if the specified parameter index has the /// specified attribute set. bool paramHasAttr(unsigned Idx, Attributes Attr) const { return getAttributes(Idx) & Attr; } - + /// getParamAlignment - Return the alignment for the specified function /// parameter. unsigned getParamAlignment(unsigned Idx) const { return Attribute::getAlignmentFromAttrs(getAttributes(Idx)); } - + /// hasAttrSomewhere - Return true if the specified attribute is set for at /// least one parameter or for the return value. bool hasAttrSomewhere(Attributes Attr) const; /// operator==/!= - Provide equality predicates. - bool operator==(const AttrListPtr &RHS) const { return AttrList == RHS.AttrList; } - bool operator!=(const AttrListPtr &RHS) const { return AttrList != RHS.AttrList; } - + bool operator==(const AttrListPtr &RHS) const + { return AttrList == RHS.AttrList; } + bool operator!=(const AttrListPtr &RHS) const + { return AttrList != RHS.AttrList; } + void dump() const; //===--------------------------------------------------------------------===// // Attribute List Introspection //===--------------------------------------------------------------------===// - + /// getRawPointer - Return a raw pointer that uniquely identifies this - /// attribute list. + /// attribute list. void *getRawPointer() const { return AttrList; } - + // Attributes are stored as a dense set of slots, where there is one // slot for each argument that has an attribute. This allows walking over the // dense set instead of walking the sparse list of attributes. - + /// isEmpty - Return true if there are no attributes. /// bool isEmpty() const { return AttrList == 0; } - - /// getNumSlots - Return the number of slots used in this attribute list. + + /// getNumSlots - Return the number of slots used in this attribute list. /// This is the number of arguments that have an attribute set on them /// (including the function itself). unsigned getNumSlots() const; - + /// getSlot - Return the AttributeWithIndex at the specified slot. This /// holds a index number plus a set of attributes. const AttributeWithIndex &getSlot(unsigned Slot) const; - + private: explicit AttrListPtr(AttributeListImpl *L); diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index c037399..9bb50d4 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -111,10 +111,11 @@ namespace bitc { enum MetadataCodes { METADATA_STRING = 1, // MDSTRING: [values] METADATA_NODE = 2, // MDNODE: [n x (type num, value num)] - METADATA_NAME = 3, // STRING: [values] - METADATA_NAMED_NODE = 4, // NAMEDMDNODE: [n x mdnodes] - METADATA_KIND = 5, // [n x [id, name]] - METADATA_ATTACHMENT = 6 // [m x [value, [n x [id, mdnode]]] + METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)] + METADATA_NAME = 4, // STRING: [values] + METADATA_NAMED_NODE = 5, // NAMEDMDNODE: [n x mdnodes] + METADATA_KIND = 6, // [n x [id, name]] + METADATA_ATTACHMENT = 7 // [m x [value, [n x [id, mdnode]]] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each // constant and maintains an implicit current type value. diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 7233f3f..4d50879 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -109,7 +109,7 @@ void SelectRoot(SelectionDAG &DAG) { #if 0 DAG.setSubgraphColor(Node, "red"); #endif - SDNode *ResNode = Select(SDValue(Node, 0)); + SDNode *ResNode = Select(Node); // If node should not be replaced, continue with the next one. if (ResNode == Node) continue; diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 806952a..9d0f0d9 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -139,7 +139,7 @@ protected: /// be emitted. virtual unsigned FastEmit_(MVT VT, MVT RetVT, - ISD::NodeType Opcode); + unsigned Opcode); /// FastEmit_r - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and @@ -147,7 +147,7 @@ protected: /// virtual unsigned FastEmit_r(MVT VT, MVT RetVT, - ISD::NodeType Opcode, unsigned Op0); + unsigned Opcode, unsigned Op0); /// FastEmit_rr - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and @@ -155,7 +155,7 @@ protected: /// virtual unsigned FastEmit_rr(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, unsigned Op1); /// FastEmit_ri - This method is called by target-independent code @@ -164,7 +164,7 @@ protected: /// virtual unsigned FastEmit_ri(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, uint64_t Imm); /// FastEmit_rf - This method is called by target-independent code @@ -173,7 +173,7 @@ protected: /// virtual unsigned FastEmit_rf(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, ConstantFP *FPImm); /// FastEmit_rri - This method is called by target-independent code @@ -182,7 +182,7 @@ protected: /// virtual unsigned FastEmit_rri(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, unsigned Op1, uint64_t Imm); /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries @@ -190,7 +190,7 @@ protected: /// If that fails, it materializes the immediate into a register and try /// FastEmit_rr instead. unsigned FastEmit_ri_(MVT VT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, uint64_t Imm, MVT ImmType); @@ -199,7 +199,7 @@ protected: /// If that fails, it materializes the immediate into a register and try /// FastEmit_rr instead. unsigned FastEmit_rf_(MVT VT, - ISD::NodeType Opcode, + unsigned Opcode, unsigned Op0, ConstantFP *FPImm, MVT ImmType); @@ -208,7 +208,7 @@ protected: /// immediate operand be emitted. virtual unsigned FastEmit_i(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, uint64_t Imm); /// FastEmit_f - This method is called by target-independent code @@ -216,7 +216,7 @@ protected: /// floating-point immediate operand be emitted. virtual unsigned FastEmit_f(MVT VT, MVT RetVT, - ISD::NodeType Opcode, + unsigned Opcode, ConstantFP *FPImm); /// FastEmitInst_ - Emit a MachineInstr with no operands and a @@ -298,7 +298,7 @@ protected: } private: - bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode); + bool SelectBinaryOp(User *I, unsigned ISDOpcode); bool SelectFNeg(User *I); @@ -308,7 +308,7 @@ private: bool SelectBitCast(User *I); - bool SelectCast(User *I, ISD::NodeType Opcode); + bool SelectCast(User *I, unsigned Opcode); }; } diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index f1bfa01..a12a55a 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -315,6 +315,8 @@ public: /// 'Orig' instruction, identical in all ways except the the instruction /// has no parent, prev, or next. /// + /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned + /// instructions. MachineInstr *CloneMachineInstr(const MachineInstr *Orig); /// DeleteMachineInstr - Delete the given MachineInstr. diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 87b67d6..c2a0578 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -288,7 +288,7 @@ public: bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound = false); - + /// addRegisterDead - We have determined MI defined a register without a use. /// Look for the operand that defines it and mark it as IsDead. If /// AddIfNotFound is true, add a implicit operand if it's not found. Returns @@ -296,6 +296,11 @@ public: bool addRegisterDead(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound = false); + /// addRegisterDefined - We have determined MI defines a register. Make sure + /// there is an operand defining Reg. + void addRegisterDefined(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo); + /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 6ca63f0..8eb0add 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -22,6 +22,7 @@ namespace llvm { class TargetInstrDesc; +class MDNode; namespace RegState { enum { @@ -123,6 +124,11 @@ public: MI->addOperand(MO); return *this; } + + const MachineInstrBuilder &addMetadata(MDNode *MD) const { + MI->addOperand(MachineOperand::CreateMetadata(MD)); + return *this; + } }; /// BuildMI - Builder interface. Specify how to create the initial instruction diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index d3df805..8459a8d 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -49,6 +49,8 @@ public: /// contiguous with the part the contains the header. MachineBasicBlock *getBottomBlock(); + void dump() const; + private: friend class LoopInfoBase<MachineBasicBlock, MachineLoop>; explicit MachineLoop(MachineBasicBlock *MBB) diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 8748afc..907c25a 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -26,6 +26,7 @@ class GlobalValue; class MachineInstr; class TargetMachine; class MachineRegisterInfo; +class MDNode; class raw_ostream; /// MachineOperand class - Representation of each machine instruction operand. @@ -42,7 +43,8 @@ public: MO_JumpTableIndex, ///< Address of indexed Jump Table for switch MO_ExternalSymbol, ///< Name of external global symbol MO_GlobalAddress, ///< Address of a global value - MO_BlockAddress ///< Address of a basic block + MO_BlockAddress, ///< Address of a basic block + MO_Metadata ///< Metadata reference (for debug info) }; private: @@ -94,6 +96,7 @@ private: MachineBasicBlock *MBB; // For MO_MachineBasicBlock. const ConstantFP *CFP; // For MO_FPImmediate. int64_t ImmVal; // For MO_Immediate. + MDNode *MD; // For MO_Metadata. struct { // For MO_Register. unsigned RegNo; @@ -158,6 +161,8 @@ public: bool isSymbol() const { return OpKind == MO_ExternalSymbol; } /// isBlockAddress - Tests if this is a MO_BlockAddress operand. bool isBlockAddress() const { return OpKind == MO_BlockAddress; } + /// isMetadata - Tests if this is a MO_Metadata operand. + bool isMetadata() const { return OpKind == MO_Metadata; } //===--------------------------------------------------------------------===// // Accessors for Register Operands @@ -311,6 +316,11 @@ public: assert(isSymbol() && "Wrong MachineOperand accessor"); return Contents.OffsetedInfo.Val.SymbolName; } + + const MDNode *getMetadata() const { + assert(isMetadata() && "Wrong MachineOperand accessor"); + return Contents.MD; + } //===--------------------------------------------------------------------===// // Mutators for various operand types. @@ -443,6 +453,13 @@ public: Op.setTargetFlags(TargetFlags); return Op; } + static MachineOperand CreateMetadata(MDNode *Meta, + unsigned char TargetFlags = 0) { + MachineOperand Op(MachineOperand::MO_Metadata); + Op.Contents.MD = Meta; + Op.setTargetFlags(TargetFlags); + return Op; + } friend class MachineInstr; friend class MachineRegisterInfo; diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 99f8c34..2203f8c 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -170,6 +170,10 @@ namespace llvm { /// instructions. FunctionPass *createMachineSinkingPass(); + /// createOptimizeExtsPass - This pass performs sign / zero extension + /// optimization by increasing uses of extended values. + FunctionPass *createOptimizeExtsPass(); + /// createStackSlotColoringPass - This pass performs stack slot coloring. FunctionPass *createStackSlotColoringPass(bool); diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index bfd3492..b33b21d 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -111,11 +111,11 @@ protected: int64_t DesiredMaskS) const; // Calls to these functions are generated by tblgen. - SDNode *Select_INLINEASM(SDValue N); - SDNode *Select_UNDEF(const SDValue &N); - SDNode *Select_EH_LABEL(const SDValue &N); - void CannotYetSelect(SDValue N); - void CannotYetSelectIntrinsic(SDValue N); + SDNode *Select_INLINEASM(SDNode *N); + SDNode *Select_UNDEF(SDNode *N); + SDNode *Select_EH_LABEL(SDNode *N); + void CannotYetSelect(SDNode *N); + void CannotYetSelectIntrinsic(SDNode *N); private: void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, @@ -131,6 +131,7 @@ private: void CodeGenAndEmitDAG(); void LowerArguments(BasicBlock *BB); + void ShrinkDemandedOps(); void ComputeLiveOutVRegInfo(); void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB); diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 9dc4c7b..0125190 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -149,7 +149,7 @@ namespace llvm { SimpleTy <= MVT::LAST_VECTOR_VALUETYPE); } - /// isPow2VectorType - Retuns true if the given vector is a power of 2. + /// isPow2VectorType - Returns true if the given vector is a power of 2. bool isPow2VectorType() const { unsigned NElts = getVectorNumElements(); return !(NElts & (NElts - 1)); @@ -437,25 +437,17 @@ namespace llvm { /// isFloatingPoint - Return true if this is a FP, or a vector FP type. bool isFloatingPoint() const { - return isSimple() ? - ((V >= MVT::f32 && V <= MVT::ppcf128) || - (V >= MVT::v2f32 && V <= MVT::v4f64)) : isExtendedFloatingPoint(); + return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint(); } /// isInteger - Return true if this is an integer, or a vector integer type. bool isInteger() const { - return isSimple() ? - ((V >= MVT::FIRST_INTEGER_VALUETYPE && - V <= MVT::LAST_INTEGER_VALUETYPE) || - (V >= MVT::v2i8 && V <= MVT::v4i64)) : isExtendedInteger(); + return isSimple() ? V.isInteger() : isExtendedInteger(); } /// isVector - Return true if this is a vector value type. bool isVector() const { - return isSimple() ? - (V >= MVT::FIRST_VECTOR_VALUETYPE && V <= - MVT::LAST_VECTOR_VALUETYPE) : - isExtendedVector(); + return isSimple() ? V.isVector() : isExtendedVector(); } /// is64BitVector - Return true if this is a 64-bit vector type. @@ -641,7 +633,7 @@ namespace llvm { static EVT getEVT(const Type *Ty, bool HandleUnknown = false); intptr_t getRawBits() { - if (V.SimpleTy <= MVT::LastSimpleValueType) + if (isSimple()) return V.SimpleTy; else return (intptr_t)(LLVMTy); diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 3c18de1..f40e8cc 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -25,6 +25,7 @@ #define LLVM_INTRINSICINST_H #include "llvm/Constants.h" +#include "llvm/Metadata.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" @@ -58,16 +59,13 @@ namespace llvm { /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics /// - struct DbgInfoIntrinsic : public IntrinsicInst { + class DbgInfoIntrinsic : public IntrinsicInst { + public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const DbgInfoIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { - case Intrinsic::dbg_stoppoint: - case Intrinsic::dbg_func_start: - case Intrinsic::dbg_region_start: - case Intrinsic::dbg_region_end: case Intrinsic::dbg_declare: case Intrinsic::dbg_value: return true; @@ -81,84 +79,16 @@ namespace llvm { static Value *StripCast(Value *C); }; - /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. - /// - struct DbgStopPointInst : public DbgInfoIntrinsic { - Value *getLineValue() const { return const_cast<Value*>(getOperand(1)); } - Value *getColumnValue() const { return const_cast<Value*>(getOperand(2)); } - MDNode *getContext() const { - return cast<MDNode>(getOperand(3)); - } - - unsigned getLine() const { - return unsigned(cast<ConstantInt>(getOperand(1))->getZExtValue()); - } - unsigned getColumn() const { - return unsigned(cast<ConstantInt>(getOperand(2))->getZExtValue()); - } - - Value *getFileName() const; - Value *getDirectory() const; - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgStopPointInst *) { return true; } - static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::dbg_stoppoint; - } - static inline bool classof(const Value *V) { - return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); - } - }; - - /// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction. - /// - struct DbgFuncStartInst : public DbgInfoIntrinsic { - MDNode *getSubprogram() const { return cast<MDNode>(getOperand(1)); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgFuncStartInst *) { return true; } - static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::dbg_func_start; - } - static inline bool classof(const Value *V) { - return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); - } - }; - - /// DbgRegionStartInst - This represents the llvm.dbg.region.start - /// instruction. - struct DbgRegionStartInst : public DbgInfoIntrinsic { - MDNode *getContext() const { return cast<MDNode>(getOperand(1)); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgRegionStartInst *) { return true; } - static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::dbg_region_start; - } - static inline bool classof(const Value *V) { - return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); - } - }; - - /// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction. - /// - struct DbgRegionEndInst : public DbgInfoIntrinsic { - MDNode *getContext() const { return cast<MDNode>(getOperand(1)); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgRegionEndInst *) { return true; } - static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::dbg_region_end; - } - static inline bool classof(const Value *V) { - return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); - } - }; - /// DbgDeclareInst - This represents the llvm.dbg.declare instruction. /// - struct DbgDeclareInst : public DbgInfoIntrinsic { - Value *getAddress() const { return getOperand(1); } + class DbgDeclareInst : public DbgInfoIntrinsic { + public: + Value *getAddress() const { + if (MDNode* MD = dyn_cast<MDNode>(getOperand(1))) + return MD->getOperand(0); + else + return NULL; + } MDNode *getVariable() const { return cast<MDNode>(getOperand(2)); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -173,10 +103,16 @@ namespace llvm { /// DbgValueInst - This represents the llvm.dbg.value instruction. /// - struct DbgValueInst : public DbgInfoIntrinsic { - Value *getValue() const; - Value *getOffset() const { return getOperand(2); } - MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); } + class DbgValueInst : public DbgInfoIntrinsic { + public: + const Value *getValue() const; + Value *getValue(); + uint64_t getOffset() const { + 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)); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const DbgValueInst *) { return true; } @@ -190,7 +126,8 @@ namespace llvm { /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. /// - struct MemIntrinsic : public IntrinsicInst { + class MemIntrinsic : public IntrinsicInst { + public: Value *getRawDest() const { return const_cast<Value*>(getOperand(1)); } Value *getLength() const { return const_cast<Value*>(getOperand(3)); } @@ -247,7 +184,8 @@ namespace llvm { /// MemSetInst - This class wraps the llvm.memset intrinsic. /// - struct MemSetInst : public MemIntrinsic { + class MemSetInst : public MemIntrinsic { + public: /// get* - Return the arguments to the instruction. /// Value *getValue() const { return const_cast<Value*>(getOperand(2)); } @@ -270,7 +208,8 @@ namespace llvm { /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics. /// - struct MemTransferInst : public MemIntrinsic { + class MemTransferInst : public MemIntrinsic { + public: /// get* - Return the arguments to the instruction. /// Value *getRawSource() const { return const_cast<Value*>(getOperand(2)); } @@ -300,7 +239,8 @@ namespace llvm { /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. /// - struct MemCpyInst : public MemTransferInst { + class MemCpyInst : public MemTransferInst { + public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemCpyInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { @@ -313,7 +253,8 @@ namespace llvm { /// MemMoveInst - This class wraps the llvm.memmove intrinsic. /// - struct MemMoveInst : public MemTransferInst { + class MemMoveInst : public MemTransferInst { + public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemMoveInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { @@ -326,7 +267,8 @@ namespace llvm { /// EHSelectorInst - This represents the llvm.eh.selector instruction. /// - struct EHSelectorInst : public IntrinsicInst { + class EHSelectorInst : public IntrinsicInst { + public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const EHSelectorInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { @@ -340,7 +282,8 @@ namespace llvm { /// MemoryUseIntrinsic - This is the common base class for the memory use /// marker intrinsics. /// - struct MemoryUseIntrinsic : public IntrinsicInst { + class MemoryUseIntrinsic : public IntrinsicInst { + public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemoryUseIntrinsic *) { return true; } diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index c472f2b..684f872 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -282,14 +282,8 @@ let Properties = [IntrNoMem] in { // optimizers can change them aggressively. Special handling needed in a few // places. let Properties = [IntrNoMem] in { - def int_dbg_stoppoint : Intrinsic<[llvm_void_ty], - [llvm_i32_ty, llvm_i32_ty, - llvm_metadata_ty]>; - def int_dbg_region_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; - def int_dbg_region_end : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; - def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; def int_dbg_declare : Intrinsic<[llvm_void_ty], - [llvm_descriptor_ty, llvm_metadata_ty]>; + [llvm_metadata_ty, llvm_metadata_ty]>; def int_dbg_value : Intrinsic<[llvm_void_ty], [llvm_metadata_ty, llvm_i64_ty, llvm_metadata_ty]>; diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 4aba210..a7e2e05 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -53,7 +53,6 @@ namespace { (void) llvm::createLibCallAliasAnalysisPass(0); (void) llvm::createScalarEvolutionAliasAnalysisPass(); (void) llvm::createBlockPlacementPass(); - (void) llvm::createBlockProfilerPass(); (void) llvm::createBreakCriticalEdgesPass(); (void) llvm::createCFGSimplificationPass(); (void) llvm::createConstantMergePass(); @@ -71,7 +70,6 @@ namespace { (void) llvm::createOptimalEdgeProfilerPass(); (void) llvm::createFunctionInliningPass(); (void) llvm::createAlwaysInlinerPass(); - (void) llvm::createFunctionProfilerPass(); (void) llvm::createGlobalDCEPass(); (void) llvm::createGlobalOptimizerPass(); (void) llvm::createGlobalsModRefPass(); @@ -120,8 +118,6 @@ namespace { (void) llvm::createTailDuplicationPass(); (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); - (void) llvm::createNullProfilerRSPass(); - (void) llvm::createRSProfilingPass(); (void) llvm::createInstCountPass(); (void) llvm::createCodeGenPreparePass(); (void) llvm::createGVNPass(); diff --git a/include/llvm/MC/MCAsmLexer.h b/include/llvm/MC/MCAsmLexer.h index da471d2..e9a6e3f 100644 --- a/include/llvm/MC/MCAsmLexer.h +++ b/include/llvm/MC/MCAsmLexer.h @@ -20,7 +20,8 @@ class SMLoc; class Target; /// AsmToken - Target independent representation for an assembler token. -struct AsmToken { +class AsmToken { +public: enum TokenKind { // Markers Eof, Error, diff --git a/include/llvm/MC/MCParsedAsmOperand.h b/include/llvm/MC/MCParsedAsmOperand.h new file mode 100644 index 0000000..7c2f5be --- /dev/null +++ b/include/llvm/MC/MCParsedAsmOperand.h @@ -0,0 +1,33 @@ +//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCASMOPERAND_H +#define LLVM_MC_MCASMOPERAND_H + +namespace llvm { +class SMLoc; + +/// MCParsedAsmOperand - This abstract class represents a source-level assembly +/// instruction operand. It should be subclassed by target-specific code. This +/// base class is used by target-independent clients and is the interface +/// between parsing an asm instruction and recognizing it. +class MCParsedAsmOperand { +public: + MCParsedAsmOperand() {} + virtual ~MCParsedAsmOperand() {} + + /// getStartLoc - Get the location of the first token of this operand. + virtual SMLoc getStartLoc() const; + /// getEndLoc - Get the location of the last token of this operand. + virtual SMLoc getEndLoc() const; +}; + +} // end namespace llvm. + +#endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index cfe04d8..eb59453 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -136,6 +136,11 @@ namespace llvm { /// dump - Print the value to stderr. void dump() const; + + /// printMangledName - Print the specified string in mangled form if it uses + /// any unusual characters. + static void printMangledName(StringRef Str, raw_ostream &OS, + const MCAsmInfo *MAI); }; } // end namespace llvm diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index ec6ba1b..179010b 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -31,7 +31,7 @@ template<typename ValueSubClass, typename ItemParentClass> //===----------------------------------------------------------------------===// -// MetadataBase - A base class for MDNode, MDString and NamedMDNode. +// MetadataBase - A base class for MDNode and MDString. class MetadataBase : public Value { protected: MetadataBase(const Type *Ty, unsigned scid) @@ -42,8 +42,7 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MetadataBase *) { return true; } static bool classof(const Value *V) { - return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal - || V->getValueID() == NamedMDNodeVal; + return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal; } }; @@ -113,6 +112,13 @@ class MDNode : public MetadataBase, public FoldingSetNode { DestroyFlag = 1 << 2 }; + // FunctionLocal enums. + enum FunctionLocalness { + FL_Unknown = -1, + FL_No = 0, + FL_Yes = 1 + }; + // Replace each instance of F from the operand list of this node with T. void replaceOperand(MDNodeOperand *Op, Value *NewVal); ~MDNode(); @@ -120,10 +126,17 @@ class MDNode : public MetadataBase, public FoldingSetNode { protected: explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, bool isFunctionLocal); + + static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, + FunctionLocalness FL); public: // Constructors and destructors. - static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals, - bool isFunctionLocal = false); + static MDNode *get(LLVMContext &Context, Value *const *Vals, + unsigned NumVals); + // getWhenValsUnresolved - Construct MDNode determining function-localness + // from isFunctionLocal argument, not by analyzing Vals. + static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals, + unsigned NumVals, bool isFunctionLocal); /// getOperand - Return specified operand. Value *getOperand(unsigned i) const; @@ -138,6 +151,11 @@ public: bool isFunctionLocal() const { return (getSubclassDataFromValue() & FunctionLocalBit) != 0; } + + // getFunction - If this metadata is function-local and recursively has a + // function-local operand, return the first such operand's parent function. + // Otherwise, return null. + Function *getFunction() const; // destroy - Delete this node. Only when there are no uses. void destroy(); @@ -167,24 +185,25 @@ private: }; //===----------------------------------------------------------------------===// -/// NamedMDNode - a tuple of other metadata. +/// NamedMDNode - a tuple of MDNodes. /// NamedMDNode is always named. All NamedMDNode operand has a type of metadata. -class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> { +class NamedMDNode : public Value, public ilist_node<NamedMDNode> { friend class SymbolTableListTraits<NamedMDNode, Module>; + friend struct ilist_traits<NamedMDNode>; friend class LLVMContextImpl; - NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT + std::string Name; Module *Parent; - void *Operands; // SmallVector<TrackingVH<MetadataBase>, 4> + void *Operands; // SmallVector<WeakVH<MDNode>, 4> void setParent(Module *M) { Parent = M; } protected: - explicit NamedMDNode(LLVMContext &C, const Twine &N, MetadataBase*const *Vals, + explicit NamedMDNode(LLVMContext &C, const Twine &N, MDNode*const *Vals, unsigned NumVals, Module *M = 0); public: - static NamedMDNode *Create(LLVMContext &C, const Twine &N, - MetadataBase *const *MDs, + static NamedMDNode *Create(LLVMContext &C, const Twine &N, + MDNode *const *MDs, unsigned NumMDs, Module *M = 0) { return new NamedMDNode(C, N, MDs, NumMDs, M); } @@ -206,14 +225,20 @@ public: inline const Module *getParent() const { return Parent; } /// getOperand - Return specified operand. - MetadataBase *getOperand(unsigned i) const; + MDNode *getOperand(unsigned i) const; /// getNumOperands - Return the number of NamedMDNode operands. unsigned getNumOperands() const; /// addOperand - Add metadata operand. - void addOperand(MetadataBase *M); - + void addOperand(MDNode *M); + + /// setName - Set the name of this named metadata. + void setName(const Twine &NewName); + + /// getName - Return a constant reference to this named metadata's name. + StringRef getName() const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const NamedMDNode *) { return true; } static bool classof(const Value *V) { diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 9a8b53a..3c8055d 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -26,6 +26,7 @@ namespace llvm { class FunctionType; class LLVMContext; +class MDSymbolTable; template<> struct ilist_traits<Function> : public SymbolTableListTraits<Function, Module> { @@ -56,6 +57,7 @@ template<> struct ilist_traits<GlobalAlias> static GlobalAlias *createSentinel(); static void destroySentinel(GlobalAlias *GA) { delete GA; } }; + template<> struct ilist_traits<NamedMDNode> : public SymbolTableListTraits<NamedMDNode, Module> { // createSentinel is used to get hold of a node that marks the end of @@ -68,6 +70,8 @@ template<> struct ilist_traits<NamedMDNode> NamedMDNode *provideInitialHead() const { return createSentinel(); } NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); } static void noteHead(NamedMDNode*, NamedMDNode*) {} + void addNodeToList(NamedMDNode *N); + void removeNodeFromList(NamedMDNode *N); private: mutable ilist_node<NamedMDNode> Sentinel; }; @@ -131,19 +135,20 @@ public: /// @name Member Variables /// @{ private: - LLVMContext &Context; ///< The LLVMContext from which types and - ///< constants are allocated. - GlobalListType GlobalList; ///< The Global Variables in the module - FunctionListType FunctionList; ///< The Functions in the module - AliasListType AliasList; ///< The Aliases in the module - LibraryListType LibraryList; ///< The Libraries needed by the module - NamedMDListType NamedMDList; ///< The named metadata in the module - std::string GlobalScopeAsm; ///< Inline Asm at global scope. - ValueSymbolTable *ValSymTab; ///< Symbol table for values - TypeSymbolTable *TypeSymTab; ///< Symbol table for types - std::string ModuleID; ///< Human readable identifier for the module - std::string TargetTriple; ///< Platform target triple Module compiled on - std::string DataLayout; ///< Target data description + LLVMContext &Context; ///< The LLVMContext from which types and + ///< constants are allocated. + GlobalListType GlobalList; ///< The Global Variables in the module + FunctionListType FunctionList; ///< The Functions in the module + AliasListType AliasList; ///< The Aliases in the module + LibraryListType LibraryList; ///< The Libraries needed by the module + NamedMDListType NamedMDList; ///< The named metadata in the module + std::string GlobalScopeAsm; ///< Inline Asm at global scope. + ValueSymbolTable *ValSymTab; ///< Symbol table for values + TypeSymbolTable *TypeSymTab; ///< Symbol table for types + std::string ModuleID; ///< Human readable identifier for the module + std::string TargetTriple; ///< Platform target triple Module compiled on + std::string DataLayout; ///< Target data description + MDSymbolTable *NamedMDSymTab; ///< NamedMDNode names. friend class Constant; @@ -379,6 +384,10 @@ public: const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; } /// Get the Module's symbol table of types TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; } + /// Get the symbol table of named metadata + const MDSymbolTable &getMDSymbolTable() const { return *NamedMDSymTab; } + /// Get the Module's symbol table of named metadata + MDSymbolTable &getMDSymbolTable() { return *NamedMDSymTab; } /// @} /// @name Global Variable Iteration diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index 3a20696..90b95bf 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -93,7 +93,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, public: typedef SuccIterator<Term_, BB_> _Self; typedef typename super::pointer pointer; - // TODO: This can be random access iterator, need operator+ and stuff tho + // TODO: This can be random access iterator, only operator[] missing. inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator assert(T && "getTerminator returned null!"); @@ -109,6 +109,10 @@ public: 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; } @@ -120,6 +124,7 @@ public: inline pointer operator->() const { return operator*(); } inline _Self& operator++() { ++idx; return *this; } // Preincrement + inline _Self operator++(int) { // Postincrement _Self tmp = *this; ++*this; return tmp; } @@ -128,6 +133,67 @@ public: inline _Self operator--(int) { // Postdecrement _Self tmp = *this; --*this; return tmp; } + + 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 { + assert(Term == x.Term && "Cannot compare iterators of different blocks!"); + return idx <= x.idx; + } + 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 { + return idx > x.idx; + assert(Term == x.Term && "Cannot compare iterators of different blocks!"); + } + + 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; + tmp += Right; + return tmp; + } + + inline _Self& operator-=(int Right) { + return operator+=(-Right); + } + + inline _Self operator-(int Right) { + return operator+(-Right); + } + + inline int operator-(const _Self& x) { + assert(Term == x.Term && "Cannot work on iterators of different blocks!"); + int distance = idx - x.idx; + return distance; + } + + // This works for read access, however write access is difficult as changes + // to Term are only possible with Term->setSuccessor(idx). Pointers that can + // be modified are not available. + // + // inline pointer operator[](int offset) { + // _Self tmp = *this; + // tmp += offset; + // return tmp.operator*(); + // } + + /// Get the source BB of this iterator. + inline BB_ *getSource() { + return Term->getParent(); + } }; typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator; diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index 09ab17c..af546f0 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -144,6 +144,10 @@ formatted_raw_ostream &fouts(); /// standard error. Use it like: ferrs() << "foo" << "bar"; formatted_raw_ostream &ferrs(); +/// fdbgs() - This returns a reference to a formatted_raw_ostream for +/// debug output. Use it like: fdbgs() << "foo" << "bar"; +formatted_raw_ostream &fdbgs(); + } // end llvm namespace diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h index 03c5648..aa230d4 100644 --- a/include/llvm/Support/Mangler.h +++ b/include/llvm/Support/Mangler.h @@ -19,6 +19,7 @@ #include <string> namespace llvm { +class Twine; class Type; class Module; class Value; @@ -101,9 +102,25 @@ public: /// specified suffix. If 'ForcePrivate' is specified, the label is specified /// to have a private label prefix. /// + /// FIXME: This is deprecated, new code should use getNameWithPrefix and use + /// MCSymbol printing to handle quotes or not etc. + /// std::string getMangledName(const GlobalValue *V, const char *Suffix = "", bool ForcePrivate = false); + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix + /// and the specified global variable's name. If the global variable doesn't + /// have a name, this fills in a unique name for the global. + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + bool isImplicitlyPrivate); + + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix + /// and the specified name as the global variable name. GVName must not be + /// empty. + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, + ManglerPrefixTy PrefixTy = Mangler::Default); + +private: /// makeNameProper - We don't want identifier names with ., space, or /// - in them, so we mangle these characters into the strings "d_", /// "s_", and "D_", respectively. This is a very simple mangling that @@ -111,14 +128,13 @@ public: /// does this for you, so there's no point calling it on the result /// from getValueName. /// - std::string makeNameProper(const std::string &x, - ManglerPrefixTy PrefixTy = Mangler::Default); + /// FIXME: This is deprecated, new code should use getNameWithPrefix and use + /// MCSymbol printing to handle quotes or not etc. + /// + void makeNameProper(SmallVectorImpl<char> &OutName, + const Twine &Name, + ManglerPrefixTy PrefixTy = Mangler::Default); - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix - /// and the specified global variable's name. If the global variable doesn't - /// have a name, this fills in a unique name for the global. - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, - bool isImplicitlyPrivate); }; } // End llvm namespace diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 438b021e..fa12416 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -160,7 +160,7 @@ inline unsigned CountLeadingZeros_32(uint32_t Value) { #else if (!Value) return 32; Count = 0; - // bisecton method for count leading zeros + // bisection method for count leading zeros for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { uint32_t Tmp = Value >> Shift; if (Tmp) { @@ -197,7 +197,7 @@ inline unsigned CountLeadingZeros_64(uint64_t Value) { if (sizeof(long) == sizeof(int64_t)) { if (!Value) return 64; Count = 0; - // bisecton method for count leading zeros + // bisection method for count leading zeros for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { uint64_t Tmp = Value >> Shift; if (Tmp) { diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index c0b6a6b..23daad9 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -437,7 +437,7 @@ m_SelectCst(const Cond &C) { // Matchers for CastInst classes // -template<typename Op_t, typename Class> +template<typename Op_t, unsigned Opcode> struct CastClass_match { Op_t Op; @@ -445,17 +445,28 @@ struct CastClass_match { template<typename OpTy> bool match(OpTy *V) { - if (Class *I = dyn_cast<Class>(V)) - return Op.match(I->getOperand(0)); + if (CastInst *I = dyn_cast<CastInst>(V)) + return I->getOpcode() == Opcode && Op.match(I->getOperand(0)); + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) + return CE->getOpcode() == Opcode && Op.match(CE->getOperand(0)); return false; } }; -template<typename Class, typename OpTy> -inline CastClass_match<OpTy, Class> m_Cast(const OpTy &Op) { - return CastClass_match<OpTy, Class>(Op); +/// m_PtrToInt +template<typename OpTy> +inline CastClass_match<OpTy, Instruction::PtrToInt> +m_PtrToInt(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::PtrToInt>(Op); } +/// m_Trunc +template<typename OpTy> +inline CastClass_match<OpTy, Instruction::Trunc> +m_Trunc(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::Trunc>(Op); +} + //===----------------------------------------------------------------------===// // Matchers for unary operators diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 6f1e066..206e42e 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -477,6 +477,13 @@ def COPY_TO_REGCLASS : Instruction { let neverHasSideEffects = 1; let isAsCheapAsAMove = 1; } +def DEBUG_VALUE : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops unknown:$value, i64imm:$offset, unknown:$meta); + let AsmString = "DEBUG_VALUE"; + let Namespace = "TargetInstrInfo"; + let isAsCheapAsAMove = 1; +} } //===----------------------------------------------------------------------===// diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index ef1fc49..1d3da8b 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -10,13 +10,15 @@ #ifndef LLVM_TARGET_TARGETPARSER_H #define LLVM_TARGET_TARGETPARSER_H -#include "llvm/MC/MCAsmLexer.h" - namespace llvm { class MCAsmParser; class MCInst; class StringRef; class Target; +class SMLoc; +class AsmToken; +class MCParsedAsmOperand; +template <typename T> class SmallVectorImpl; /// TargetAsmParser - Generic interface to target specific assembly parsers. class TargetAsmParser { @@ -43,9 +45,11 @@ public: // /// \param AP - The current parser object. /// \param Name - The instruction name. - /// \param Inst [out] - On success, the parsed instruction. + /// \param Operands [out] - The list of parsed operands, this returns + /// ownership of them to the caller. /// \return True on failure. - virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst) = 0; + virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, + SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; /// ParseDirective - Parse a target specific assembler directive /// @@ -58,6 +62,14 @@ public: /// /// \param ID - the identifier token of the directive. virtual bool ParseDirective(AsmToken DirectiveID) = 0; + + /// MatchInstruction - Recognize a series of operands of a parsed instruction + /// as an actual MCInst. This returns false and fills in Inst on success and + /// returns true on failure to match. + virtual bool + MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, + MCInst &Inst) = 0; + }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 1bcd6fd..8e2157e 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -88,7 +88,10 @@ public: /// only needed in cases where the register classes implied by the /// instructions are insufficient. The actual MachineInstrs to perform /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. - COPY_TO_REGCLASS = 10 + COPY_TO_REGCLASS = 10, + + // DEBUG_VALUE - a mapping of the llvm.dbg.value intrinsic + DEBUG_VALUE = 11 }; unsigned getNumOpcodes() const { return NumOpcodes; } @@ -143,6 +146,18 @@ public: return false; } + /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" + /// extension instruction. That is, it's like a copy where it's legal for the + /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns + /// true, then it's expected the pre-extension value is available as a subreg + /// of the result register. This also returns the sub-register index in + /// SubIdx. + virtual bool isCoalescableExtInstr(const MachineInstr &MI, + unsigned &SrcReg, unsigned &DstReg, + unsigned &SubIdx) const { + return false; + } + /// isIdentityCopy - Return true if the instruction is a copy (or /// extract_subreg, insert_subreg, subreg_to_reg) where the source and /// destination registers are the same. @@ -232,6 +247,14 @@ public: const MachineInstr *Orig, const TargetRegisterInfo *TRI) const = 0; + /// duplicate - Create a duplicate of the Orig instruction in MF. This is like + /// MachineFunction::CloneMachineInstr(), but the target may update operands + /// that are required to be unique. + /// + /// The instruction must be duplicable as indicated by isNotDuplicable(). + virtual MachineInstr *duplicate(MachineInstr *Orig, + MachineFunction &MF) const = 0; + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into one or more true @@ -560,6 +583,8 @@ public: unsigned DestReg, unsigned SubReg, const MachineInstr *Orig, const TargetRegisterInfo *TRI) const; + virtual MachineInstr *duplicate(MachineInstr *Orig, + MachineFunction &MF) const; virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other, const MachineRegisterInfo *MRI) const; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index dd28a87..15da845 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -774,10 +774,12 @@ public: /// that want to combine struct TargetLoweringOpt { SelectionDAG &DAG; + bool ShrinkOps; SDValue Old; SDValue New; - explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {} + explicit TargetLoweringOpt(SelectionDAG &InDAG, bool Shrink = false) : + DAG(InDAG), ShrinkOps(Shrink) {} bool CombineTo(SDValue O, SDValue N) { Old = O; @@ -1478,7 +1480,7 @@ public: } /// isZExtFree - Return true if any actual instruction that defines a - /// value of type Ty1 implicit zero-extends the value to Ty2 in the result + /// value of type Ty1 implicitly zero-extends the value to Ty2 in the result /// register. This does not necessarily include registers defined in /// unknown ways, such as incoming arguments, or copies from unknown /// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 9a64191..3dd7471 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -352,7 +352,7 @@ public: /// getCOFFSection - Return the MCSection for the specified COFF section. /// FIXME: Switch this to a semantic view eventually. - const MCSection *getCOFFSection(const char *Name, bool isDirective, + const MCSection *getCOFFSection(StringRef Name, bool isDirective, SectionKind K) const; }; diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index dec0b1d..f93eadb 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -664,7 +664,7 @@ public: /// frame indices from instructions which may use them. The instruction /// referenced by the iterator contains an MO_FrameIndex operand which must be /// eliminated by this method. This method may modify or replace the - /// specified instruction, as long as it keeps the iterator pointing the the + /// specified instruction, as long as it keeps the iterator pointing at the /// finished product. SPAdj is the SP adjustment due to call frame setup /// instruction. /// diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 7f54f81..4b72f81 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -843,11 +843,6 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>; // Complex pattern definitions. // -class CPAttribute; -// Pass the parent Operand as root to CP function rather -// than the root of the sub-DAG -def CPAttrParentAsRoot : CPAttribute; - // Complex patterns, e.g. X86 addressing mode, requires pattern matching code // in C++. NumOperands is the number of operands returned by the select function; // SelectFunc is the name of the function used to pattern match the max. pattern; @@ -855,12 +850,10 @@ def CPAttrParentAsRoot : CPAttribute; // e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; // class ComplexPattern<ValueType ty, int numops, string fn, - list<SDNode> roots = [], list<SDNodeProperty> props = [], - list<CPAttribute> attrs = []> { + list<SDNode> roots = [], list<SDNodeProperty> props = []> { ValueType Ty = ty; int NumOperands = numops; string SelectFunc = fn; list<SDNode> RootNodes = roots; list<SDNodeProperty> Properties = props; - list<CPAttribute> Attributes = attrs; } diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 9794ffd..9c579ac 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -19,22 +19,12 @@ namespace llvm { class ModulePass; class FunctionPass; -// Insert function profiling instrumentation -ModulePass *createFunctionProfilerPass(); - -// Insert block profiling instrumentation -ModulePass *createBlockProfilerPass(); - // Insert edge profiling instrumentation ModulePass *createEdgeProfilerPass(); // Insert optimal edge profiling instrumentation ModulePass *createOptimalEdgeProfilerPass(); -// Random Sampling Profiling Framework -ModulePass* createNullProfilerRSPass(); -FunctionPass* createRSProfilingPass(); - } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 8172114..3f4571e 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -40,8 +40,9 @@ void FoldSingleEntryPHINodes(BasicBlock *BB); /// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it /// is dead. Also recursively delete any operands that become dead as /// a result. This includes tracing the def-use list from the PHI to see if -/// it is ultimately unused or if it reaches an unused cycle. -void DeleteDeadPHIs(BasicBlock *BB); +/// it is ultimately unused or if it reaches an unused cycle. Return true +/// if any PHIs were deleted. +bool DeleteDeadPHIs(BasicBlock *BB); /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. @@ -65,11 +66,6 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL, // void ReplaceInstWithInst(Instruction *From, Instruction *To); -/// CopyPrecedingStopPoint - If I is immediately preceded by a StopPoint, -/// make a copy of the stoppoint before InsertPos (presumably before copying -/// or moving I). -void CopyPrecedingStopPoint(Instruction *I, BasicBlock::iterator InsertPos); - /// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the /// instruction before ScanFrom) checking to see if we have the value at the /// memory address *Ptr locally available within a small number of instructions. diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 2cdd31f..0b8147e 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -27,7 +27,7 @@ class PHINode; class AllocaInst; class ConstantExpr; class TargetData; -struct DbgInfoIntrinsic; +class DbgInfoIntrinsic; template<typename T> class SmallVectorImpl; @@ -63,16 +63,25 @@ bool isInstructionTriviallyDead(Instruction *I); /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands -/// trivially dead, delete them too, recursively. -void RecursivelyDeleteTriviallyDeadInstructions(Value *V); +/// trivially dead, delete them too, recursively. Return true if any +/// instructions were deleted. +bool RecursivelyDeleteTriviallyDeadInstructions(Value *V); /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively /// dead PHI node, due to being a def-use chain of single-use nodes that /// either forms a cycle or is terminated by a trivially dead instruction, /// delete it. If that makes any of its operands trivially dead, delete them -/// too, recursively. -void RecursivelyDeleteDeadPHINode(PHINode *PN); +/// too, recursively. Return true if the PHI node is actually deleted. +bool RecursivelyDeleteDeadPHINode(PHINode *PN); + +/// SimplifyInstructionsInBlock - Scan the specified basic block and try to +/// simplify any instructions in it and recursively delete dead instructions. +/// +/// This returns true if it changed the code, note that it can delete +/// instructions in other blocks as well in this block. +bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); + //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring. // diff --git a/include/llvm/Type.h b/include/llvm/Type.h index e516982..2c37a68 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -217,6 +217,9 @@ public: /// bool isInteger() const { return ID == IntegerTyID; } + /// isInteger - Return true if this is an IntegerType of the specified width. + bool isInteger(unsigned Bitwidth) const; + /// isIntOrIntVector - Return true if this is an integer type or a vector of /// integer types. /// diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h index e05fdbd..53815ba 100644 --- a/include/llvm/ValueSymbolTable.h +++ b/include/llvm/ValueSymbolTable.h @@ -17,6 +17,7 @@ #include "llvm/Value.h" #include "llvm/ADT/StringMap.h" #include "llvm/System/DataTypes.h" +#include "llvm/ADT/ilist_node.h" namespace llvm { template<typename ValueSubClass, typename ItemParentClass> @@ -26,7 +27,7 @@ namespace llvm { class NamedMDNode; class Module; class StringRef; - + /// This class provides a symbol table of name/value pairs. It is essentially /// a std::map<std::string,Value*> but has a controlled interface provided by /// LLVM as well as ensuring uniqueness of names. @@ -39,7 +40,6 @@ class ValueSymbolTable { friend class SymbolTableListTraits<Function, Module>; friend class SymbolTableListTraits<GlobalVariable, Module>; friend class SymbolTableListTraits<GlobalAlias, Module>; - friend class SymbolTableListTraits<NamedMDNode, Module>; /// @name Types /// @{ public: @@ -129,6 +129,88 @@ private: /// @} }; +/// This class provides a symbol table of name/NamedMDNode pairs. It is +/// essentially a StringMap wrapper. + +class MDSymbolTable { + friend class SymbolTableListTraits<NamedMDNode, Module>; +/// @name Types +/// @{ +private: + /// @brief A mapping of names to metadata + typedef StringMap<NamedMDNode*> MDMap; + +public: + /// @brief An iterator over a ValueMap. + typedef MDMap::iterator iterator; + + /// @brief A const_iterator over a ValueMap. + typedef MDMap::const_iterator const_iterator; + +/// @} +/// @name Constructors +/// @{ +public: + + MDSymbolTable(const MDNode &); // DO NOT IMPLEMENT + void operator=(const MDSymbolTable &); // DO NOT IMPLEMENT + MDSymbolTable() : mmap(0) {} + ~MDSymbolTable(); + +/// @} +/// @name Accessors +/// @{ +public: + + /// This method finds the value with the given \p Name in the + /// the symbol table. + /// @returns the NamedMDNode associated with the \p Name + /// @brief Lookup a named Value. + NamedMDNode *lookup(StringRef Name) const { return mmap.lookup(Name); } + + /// @returns true iff the symbol table is empty + /// @brief Determine if the symbol table is empty + inline bool empty() const { return mmap.empty(); } + + /// @brief The number of name/type pairs is returned. + inline unsigned size() const { return unsigned(mmap.size()); } + +/// @} +/// @name Iteration +/// @{ +public: + /// @brief Get an iterator that from the beginning of the symbol table. + inline iterator begin() { return mmap.begin(); } + + /// @brief Get a const_iterator that from the beginning of the symbol table. + inline const_iterator begin() const { return mmap.begin(); } + + /// @brief Get an iterator to the end of the symbol table. + inline iterator end() { return mmap.end(); } + + /// @brief Get a const_iterator to the end of the symbol table. + inline const_iterator end() const { return mmap.end(); } + +/// @} +/// @name Mutators +/// @{ +public: + /// insert - The method inserts a new entry into the stringmap. + void insert(StringRef Name, NamedMDNode *Node) { + (void) mmap.GetOrCreateValue(Name, Node); + } + + /// This method removes a NamedMDNode from the symbol table. + void remove(StringRef Name) { mmap.erase(Name); } + +/// @} +/// @name Internal Data +/// @{ +private: + MDMap mmap; ///< The map that holds the symbol table. +/// @} +}; + } // End llvm namespace #endif |