[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