[llvm] [DA] batch delinearization (PR #170519)

Ryotaro Kasuga via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 06:54:51 PST 2025


================
@@ -960,3 +960,140 @@ PreservedAnalyses DelinearizationPrinterPass::run(Function &F,
                        &AM.getResult<ScalarEvolutionAnalysis>(F));
   return PreservedAnalyses::all();
 }
+
+//===----------------------------------------------------------------------===//
+// BatchDelinearization Implementation
+//===----------------------------------------------------------------------===//
+
+/// Return true for a Load or Store instruction.
+static bool isLoadOrStore(const Instruction *I) {
+  return isa<LoadInst>(I) || isa<StoreInst>(I);
+}
+
+void BatchDelinearization::populate() {
+  if (Populated)
+    return;
+
+  Populated = true;
+
+  // Step 1: Collect all memory accesses grouped by base pointer.
+  // Map from base pointer to list of (Instruction, AccessFunction) pairs.
+  SmallDenseMap<const SCEVUnknown *,
+                SmallVector<std::pair<Instruction *, const SCEV *>, 4>, 8>
+      AccessesByBase;
+
+  for (Instruction &I : instructions(F)) {
+    if (!isLoadOrStore(&I))
+      continue;
+
+    Value *Ptr = getLoadStorePointerOperand(&I);
+    Loop *L = LI.getLoopFor(I.getParent());
+    const SCEV *AccessFn = SE.getSCEVAtScope(Ptr, L);
+    const SCEVUnknown *Base =
+        dyn_cast<SCEVUnknown>(SE.getPointerBase(AccessFn));
+
+    if (!Base)
+      continue;
+
+    // Only consider accesses where the base is loop invariant.
+    if (L && !SE.isLoopInvariant(Base, L))
+      continue;
+
+    AccessesByBase[Base].push_back({&I, AccessFn});
+  }
+
+  // Step 2: For each base pointer, collect terms from ALL accesses and
+  // compute array dimensions once.
+  for (auto &Entry : AccessesByBase) {
+    const SCEVUnknown *Base = Entry.first;
+    auto &Accesses = Entry.second;
+
+    // Skip if there's only one access - no benefit from batch processing.
+    if (Accesses.size() < 2)
+      continue;
+
+    // Determine element size - use the smallest among all accesses.
+    const SCEV *ElemSize = nullptr;
+    for (auto &Access : Accesses) {
+      const SCEV *EltSize = SE.getElementSize(Access.first);
+      if (!ElemSize)
+        ElemSize = EltSize;
+      else if (SE.isKnownPredicate(ICmpInst::ICMP_ULT, EltSize, ElemSize))
+        ElemSize = EltSize;
----------------
kasuga-fj wrote:

I think we should bail out if a different element size is found. Handling multiple element sizes seems risky.

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


More information about the llvm-commits mailing list