[llvm] [SSAUpdaterBulk] Add PHI simplification pass. (PR #132004)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 19 04:09:27 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Valery Pykhtin (vpykhtin)

<details>
<summary>Changes</summary>

This patch, along with https://github.com/llvm/llvm-project/pull/131762, enhances SSAUpdaterBulk to function as a near drop-in replacement for SSAUpdater, see https://github.com/llvm/llvm-project/pull/130611.

I opted to implement phi optimization as a separate step to maintain the current behavior of `SSAUpdaterBulk::RewriteAllUses` while ensuring the implementation remains straightforward.

---
Full diff: https://github.com/llvm/llvm-project/pull/132004.diff


2 Files Affected:

- (modified) llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h (+24) 
- (modified) llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp (+47) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
index ad24cb454d5e7..6894e4fa0a357 100644
--- a/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
+++ b/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
@@ -79,6 +79,30 @@ class SSAUpdaterBulk {
   /// vector.
   void RewriteAllUses(DominatorTree *DT,
                       SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
+
+  /// Rewrite all uses and simplify the inserted PHI nodes.
+  /// Use this method to preserve behavior when replacing SSAUpdater.
+  void RewriteAndSimplifyAllUses(DominatorTree *DT) {
+    SmallVector<PHINode *, 8> NewPHIs;
+    RewriteAllUses(DT, &NewPHIs);
+    simplifyPass(NewPHIs);
+  }
+
+  /// Same as previous, but return inserted PHI nodes in InsertedPHIs.
+  void RewriteAndSimplifyAllUses(DominatorTree *DT,
+                                 SmallVectorImpl<PHINode *> &InsertedPHIs) {
+    RewriteAllUses(DT, &InsertedPHIs);
+    simplifyPass(InsertedPHIs);
+    // Remove nullptrs from the worklist
+    InsertedPHIs.erase(
+        std::remove(InsertedPHIs.begin(), InsertedPHIs.end(), nullptr),
+        InsertedPHIs.end());
+  }
+
+private:
+  /// Perform a single pass of simplification over the worklist of PHIs.
+  /// Pointers to replaced phis are nulled out.
+  static bool simplifyPass(SmallVectorImpl<PHINode *> &Worklist);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
index cad7ff64c01fb..dac964b092ec5 100644
--- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
+++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/SSAUpdaterBulk.h"
+#include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/IteratedDominanceFrontier.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Dominators.h"
@@ -182,3 +183,49 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
     }
   }
 }
+
+static bool isEquivalentPHI(PHINode *PHI1, PHINode *PHI2) {
+  if (PHI1->getNumIncomingValues() != PHI2->getNumIncomingValues())
+    return false;
+
+  unsigned I = 0, NumValues = PHI1->getNumIncomingValues();
+  for (; I != NumValues; ++I) {
+    if (PHI1->getIncomingBlock(I) != PHI2->getIncomingBlock(I))
+      break;
+    if (PHI1->getIncomingValue(I) != PHI2->getIncomingValue(I))
+      return false;
+  }
+  // TODO: add procesing if phis have different order of incoming values.
+  return I == NumValues;
+}
+
+bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl<PHINode *> &Worklist) {
+  if (Worklist.empty())
+    return false;
+
+  auto findEquivalentPHI = [](PHINode *PHI) -> Value * {
+    BasicBlock *BB = PHI->getParent();
+    for (auto &OtherPHI : BB->phis()) {
+      if (PHI != &OtherPHI && isEquivalentPHI(PHI, &OtherPHI)) {
+        return &OtherPHI;
+      }
+    }
+    return nullptr;
+  };
+
+  const DataLayout &DL = Worklist.front()->getParent()->getDataLayout();
+  bool Change = false;
+  for (PHINode *&PHI : Worklist) {
+    Value *Replacement = simplifyInstruction(PHI, DL);
+    if (!Replacement)
+      Replacement = findEquivalentPHI(PHI);
+
+    if (Replacement) {
+      PHI->replaceAllUsesWith(Replacement);
+      PHI->eraseFromParent();
+      PHI = nullptr; // Mark as removed
+      Change = true;
+    }
+  }
+  return Change;
+}

``````````

</details>


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


More information about the llvm-commits mailing list