[llvm] r214135 - IR: Optimize size of use-list order shuffle vectors

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Jul 28 15:41:50 PDT 2014


Author: dexonsmith
Date: Mon Jul 28 17:41:50 2014
New Revision: 214135

URL: http://llvm.org/viewvc/llvm-project?rev=214135&view=rev
Log:
IR: Optimize size of use-list order shuffle vectors

Since we're storing lots of these, save two-pointers per vector with a
custom type rather than using the relatively heavy `SmallVector`.

Part of PR5680.

Modified:
    llvm/trunk/include/llvm/IR/UseListOrder.h
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp

Modified: llvm/trunk/include/llvm/IR/UseListOrder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/UseListOrder.h?rev=214135&r1=214134&r2=214135&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/UseListOrder.h (original)
+++ llvm/trunk/include/llvm/IR/UseListOrder.h Mon Jul 28 17:41:50 2014
@@ -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<unsigned, 8> 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<UseListOrder> UseListOrderStack;

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=214135&r1=214134&r2=214135&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Mon Jul 28 17:41:50 2014
@@ -133,12 +133,11 @@ static void predictValueUseListOrderImpl
     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,





More information about the llvm-commits mailing list