[llvm] [IR] Add logical SROA pass (PR #192058)
Nathan Gauër via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 01:52:00 PDT 2026
================
@@ -0,0 +1,205 @@
+//===- LSROA.cpp - Logical Scalar Replacement Of Aggregates ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This transformation implements the well known scalar replacement of
+/// aggregates transformation. It tries to identify promotable elements of an
+/// aggregate alloca, and promote them to registers. It will also try to
+/// convert uses of an element (or set of elements) of an alloca into a vector
+/// or bitfield-style integer scalar if appropriate.
+///
+/// It works to do this with minimal slicing of the alloca so that regions
+/// which are merely transferred in and out of external memory remain unchanged
+/// and are not decomposed to scalar code.
+///
+/// Because this also performs alloca promotion, it can be thought of as also
+/// serving the purpose of SSA formation. The algorithm iterates on the
+/// function until all opportunities for promotion have been realized.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/LSROA.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Scalar.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "lsroa"
+
+namespace {
+
+class LSROA {
+public:
+ LSROA() {}
+
+ bool runLSROA(Function &F);
+
+private:
+ bool runOnStructuredAlloca(StructuredAllocaInst &SAI);
+};
+
+} // end anonymous namespace
+
+bool LSROA::runOnStructuredAlloca(StructuredAllocaInst &SAI) {
+ // For now, LSROA only handles SGEP on structs.
+ StructType *ST = dyn_cast<StructType>(SAI.getAllocationType());
+ if (!ST)
+ return false;
+
+ SmallVector<SmallVector<StructuredGEPInst *, 4>, 4> FieldUsers(
+ ST->getNumElements());
+ for (const auto &user : SAI.users()) {
+ // Lifetime intrinsincs are handled differently.
+ auto II = dyn_cast<IntrinsicInst>(user);
+ if (II && II->isLifetimeStartOrEnd())
+ continue;
+
+ auto SGEP = dyn_cast<StructuredGEPInst>(user);
+ // If any user is not an SGEP, we bail out.
+ if (!SGEP) {
+ return false;
+ }
+
+ // If the SGEP has no indices, this means we have a pointer on the whole
+ // struct. For now, we bail out: if it was not used, it would be DCE'd, so
+ // there is probably a reference to the whole struct somewhere.
+ if (SGEP->getNumIndices() == 0)
+ return false;
----------------
Keenuts wrote:
That would be the job of InstSimplify -> we should remove SGEP with no indices and fold the ptr operand in the user.
https://github.com/llvm/llvm-project/pull/192058
More information about the llvm-commits
mailing list