diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h index 4326182c366..a0eb0a6ce1b 100644 --- a/include/llvm/IR/UseListOrder.h +++ b/include/llvm/IR/UseListOrder.h @@ -25,11 +25,58 @@ class Module; class Function; class Value; +/// \brief Structure to hold a use-list shuffle vector. +/// +/// Stores most use-lists locally, but large use-lists use an extra heap entry. +/// Costs two fewer pointers than the equivalent \a SmallVector. +class UseListShuffleVector { + unsigned Size; + union { + unsigned *Ptr; + unsigned Array[6]; + } Storage; + + bool isSmall() const { return Size <= 6; } + unsigned *data() { return isSmall() ? Storage.Array : Storage.Ptr; } + const unsigned *data() const { + return isSmall() ? Storage.Array : Storage.Ptr; + } + +public: + UseListShuffleVector() : Size(0) {} + UseListShuffleVector(UseListShuffleVector &&X) { + std::memcpy(this, &X, sizeof(UseListShuffleVector)); + X.Size = 0; + } + explicit UseListShuffleVector(size_t Size) : Size(Size) { + if (!isSmall()) + Storage.Ptr = new unsigned[Size]; + } + ~UseListShuffleVector() { + if (!isSmall()) + delete Storage.Ptr; + } + + typedef unsigned *iterator; + typedef const unsigned *const_iterator; + + size_t size() const { return Size; } + iterator begin() { return data(); } + iterator end() { return begin() + size(); } + const_iterator begin() const { return data(); } + const_iterator end() const { return begin() + size(); } + unsigned &operator[](size_t I) { return data()[I]; } + unsigned operator[](size_t I) const { return data()[I]; } +}; + /// \brief Structure to hold a use-list order. struct UseListOrder { - const Function *F; const Value *V; - SmallVector Shuffle; + const Function *F; + UseListShuffleVector Shuffle; + + UseListOrder(const Value *V, const Function *F, size_t ShuffleSize) + : V(V), F(F), Shuffle(ShuffleSize) {} }; typedef std::vector UseListOrderStack; diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 0421332e530..273ea06c641 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -133,12 +133,11 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, return; // Store the shuffle. - UseListOrder O; - O.V = V; - O.F = F; - for (auto &I : List) - O.Shuffle.push_back(I.second); - Stack.push_back(O); + UseListOrder O(V, F, List.size()); + assert(List.size() == O.Shuffle.size() && "Wrong size"); + for (size_t I = 0, E = List.size(); I != E; ++I) + O.Shuffle[I] = List[I].second; + Stack.emplace_back(std::move(O)); } static void predictValueUseListOrder(const Value *V, const Function *F,