[llvm] [SandboxVectorizer] Add container class to track and manage SeedBundles (PR #112048)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 15 09:23:28 PDT 2024


================
@@ -162,5 +167,123 @@ template <typename LoadOrStoreT> class MemSeedBundle : public SeedBundle {
 using StoreSeedBundle = MemSeedBundle<sandboxir::StoreInst>;
 using LoadSeedBundle = MemSeedBundle<sandboxir::LoadInst>;
 
+/// Class to conveniently track Seeds within SeedBundles. Saves newly collected
+/// seeds in the proper bundle. Supports constant-time removal, as seeds and
+/// entire bundles are vectorized and marked used to signify removal. Iterators
+/// skip bundles that are completely used.
+class SeedContainer {
+  // Use the same key for different seeds if they are the same type and
+  // reference the same pointer, even if at different offsets. This directs
+  // potentially vectorizable seeds into the same bundle.
+  using KeyT = std::tuple<Value *, Type *, Instruction::Opcode>;
+  // Trying to vectorize too many seeds at once is expensive in
+  // compilation-time. Use a vector of bundles (all with the same key) to
+  // partition the candidate set into more manageable units. Each bundle is
+  // size-limited by sbvec-seed-bundle-size-limit.  TODO: There might be a
+  // better way to divide these than by simple insertion order.
+  using ValT = SmallVector<std::unique_ptr<SeedBundle>>;
+  using BundleMapT = MapVector<KeyT, ValT>;
+  // Map from {pointer, Type, Opcode} to a vector of bundles.
+  BundleMapT Bundles;
+  // Allows finding a particular Instruction's bundle.
+  DenseMap<Instruction *, SeedBundle *> SeedLookupMap;
+
+  ScalarEvolution &SE;
+
+  template <typename LoadOrStoreT> KeyT getKey(LoadOrStoreT *LSI) const;
+
+public:
+  SeedContainer(ScalarEvolution &SE) : SE(SE) {}
+
+  class iterator {
+    BundleMapT *Map = nullptr;
+    BundleMapT::iterator MapIt;
+    ValT *Vec = nullptr;
+    size_t VecIdx;
+
+  public:
+    using difference_type = std::ptrdiff_t;
+    using value_type = SeedBundle;
+    using pointer = value_type *;
+    using reference = value_type &;
+    using iterator_category = std::input_iterator_tag;
+
+    /// Iterates over the \p Map of SeedBundle Vectors, starting at \p MapIt,
+    /// and \p Vec at \p VecIdx, skipping vectors that are completely
+    /// used. Iteration order over the keys {Pointer, Type, Opcode} follows
+    /// DenseMap iteration order. For a given key, the vectors of
+    /// SeedBundles will be returned in insertion order. As in the
+    /// pseudo code below:
+    ///
+    /// for Key,Value in Bundles
+    ///   for SeedBundleVector in Value
+    ///     for SeedBundle in SeedBundleVector
+    ///        if !SeedBundle.allUsed() ...
+    ///
+    /// Note that the bundles themselves may have additional ordering, created
+    /// by the subclasses by insertAt. The bundles themselves may also have used
+    /// instructions.
+    iterator(BundleMapT &Map, BundleMapT::iterator MapIt, ValT *Vec, int VecIdx)
+        : Map(&Map), MapIt(MapIt), Vec(Vec), VecIdx(VecIdx) {}
+    value_type &operator*() {
+      assert(Vec != nullptr && "Already at end!");
+      return *(*Vec)[VecIdx];
+    }
+    // Skip completely used bundles by repeatedly calling operator++().
+    void skipUsed() {
+      while (Vec && VecIdx < Vec->size() && this->operator*().allUsed())
+        ++(*this);
+    }
+    // Iterators iterate over the bundles
+    iterator &operator++() {
+      assert(VecIdx >= 0 && "Already at end!");
----------------
Sterling-Augustine wrote:

Fixed in https://github.com/llvm/llvm-project/pull/112392 

Sorry for the trouble

https://github.com/llvm/llvm-project/pull/112048


More information about the llvm-commits mailing list