[llvm] [DA] batch delinearization (PR #170519)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 12 06:54:52 PST 2025
================
@@ -164,6 +171,84 @@ bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes);
+/// BatchDelinearization - A wrapper for batch delinearization that caches
+/// results across multiple queries. Similar to BatchAAResults, this class
+/// should be used when analyzing multiple memory accesses to the same base
+/// pointers, as it computes array dimensions once using terms from all
+/// accesses, leading to better precision.
+///
+/// This class collects all memory accesses in a function, groups them by base
+/// pointer, and computes array dimensions for each base pointer using terms
+/// from all accesses. The results are cached for efficient lookups during
+/// dependence analysis.
+///
+/// Usage:
+/// BatchDelinearization BD(F, SE, LI);
+/// BD.populate(); // Compute and cache delinearization info.
+/// // Then pass BD to DependenceInfo or query it directly.
+class LLVM_ABI BatchDelinearization {
+public:
+ BatchDelinearization(Function &F, ScalarEvolution &SE, LoopInfo &LI)
+ : F(F), SE(SE), LI(LI) {}
+
+ /// Populate the cache with delinearization information for all memory
+ /// accesses in the function.
+ void populate();
+
+ /// Check if the cache has been populated.
+ bool isPopulated() const { return Populated; }
+
+ /// Get the cached array sizes for a base pointer.
+ /// Returns nullptr if not found.
+ const SmallVector<const SCEV *, 4> *
+ getArraySizes(const SCEVUnknown *Base) const {
+ auto It = ArraySizes.find(Base);
+ return It != ArraySizes.end() ? &It->second : nullptr;
+ }
+
+ /// Get the cached subscripts for an instruction.
+ /// Returns nullptr if not found.
+ const SmallVector<const SCEV *, 4> *
+ getSubscripts(const Instruction *I) const {
+ auto It = Subscripts.find(I);
+ return It != Subscripts.end() ? &It->second : nullptr;
+ }
+
+ /// Get the cached element size for a base pointer.
+ /// Returns nullptr if not found.
+ const SCEV *getElementSize(const SCEVUnknown *Base) const {
+ auto It = ElementSizes.find(Base);
+ return It != ElementSizes.end() ? It->second : nullptr;
+ }
+
+ /// Get the ScalarEvolution instance.
+ ScalarEvolution &getSE() { return SE; }
+ const ScalarEvolution &getSE() const { return SE; }
+
+ /// Get the LoopInfo instance.
+ LoopInfo &getLI() { return LI; }
+ const LoopInfo &getLI() const { return LI; }
+
+private:
+ Function &F;
+ ScalarEvolution &SE;
+ LoopInfo &LI;
+
+ /// Map from base pointer to computed array dimension sizes.
+ SmallDenseMap<const SCEVUnknown *, SmallVector<const SCEV *, 4>, 8>
+ ArraySizes;
+
+ /// Map from instruction to pre-computed subscripts.
+ SmallDenseMap<const Instruction *, SmallVector<const SCEV *, 4>, 16>
+ Subscripts;
+
+ /// Element size for the array (used for validation).
+ SmallDenseMap<const SCEVUnknown *, const SCEV *, 8> ElementSizes;
+
+ /// Flag indicating whether the cache has been populated.
+ bool Populated = false;
----------------
kasuga-fj wrote:
Consider using [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization) rather than holding such a flag.
https://github.com/llvm/llvm-project/pull/170519
More information about the llvm-commits
mailing list