Index: include/llvm/ADT/SmallPtrSet.h =================================================================== --- include/llvm/ADT/SmallPtrSet.h +++ include/llvm/ADT/SmallPtrSet.h @@ -26,6 +26,10 @@ #include #include +#if LLVM_ENABLE_ABI_BREAKING_CHECKS +extern bool ReverseIterate; +#endif + namespace llvm { class SmallPtrSetIteratorImpl; @@ -205,7 +209,12 @@ public: explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E) : Bucket(BP), End(E) { - AdvanceIfNotValid(); +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + if (ReverseIterate) + RetreatIfNotValid(); + else +#endif + AdvanceIfNotValid(); } bool operator==(const SmallPtrSetIteratorImpl &RHS) const { @@ -226,6 +235,17 @@ *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) ++Bucket; } +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + void RetreatIfNotValid() { + --Bucket; + assert(Bucket <= End); + while (Bucket != End && + (*Bucket == SmallPtrSetImplBase::getEmptyMarker() || + *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) { + --Bucket; + } + } +#endif }; /// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. @@ -251,13 +271,29 @@ } inline SmallPtrSetIterator& operator++() { // Preincrement +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + if (ReverseIterate) + RetreatIfNotValid(); + else { + ++Bucket; + AdvanceIfNotValid(); + } +#else ++Bucket; AdvanceIfNotValid(); +#endif return *this; } SmallPtrSetIterator operator++(int) { // Postincrement - SmallPtrSetIterator tmp = *this; ++*this; return tmp; + SmallPtrSetIterator tmp = *this; +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + if (ReverseIterate) + --*this; + else +#endif + ++*this; + return tmp; } }; @@ -342,9 +378,23 @@ } inline iterator begin() const { +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + if (ReverseIterate) + return endPtr(); +#endif return iterator(CurArray, EndPointer()); } + inline iterator end() const { +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + if (ReverseIterate) + return iterator(CurArray, CurArray); +#endif + return endPtr(); + } + +private: + inline iterator endPtr() const { const void *const *End = EndPointer(); return iterator(End, End); } Index: lib/Support/CommandLine.cpp =================================================================== --- lib/Support/CommandLine.cpp +++ lib/Support/CommandLine.cpp @@ -45,6 +45,16 @@ #define DEBUG_TYPE "commandline" +// If LLVM_ENABLE_ABI_BREAKING_CHECKS is set the flag -mllvm -reverse-iterate +// can be used to toggle forward/reverse iteration of unordered containers. +// This will help uncover differences in codegen caused due to undefined +// iteration order. +#if LLVM_ENABLE_ABI_BREAKING_CHECKS +bool ReverseIterate; +static cl::opt ReverseIteration("reverse-iterate", + cl::location(ReverseIterate), cl::init(true)); +#endif + //===----------------------------------------------------------------------===// // Template instantiations and anchors. //