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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 6 12:42:18 PDT 2025


================
@@ -223,3 +224,78 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
     }
   }
 }
+
+bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl<PHINode *> &Worklist) {
+  if (Worklist.empty())
+    return false;
+
+  const DataLayout &DL = Worklist.front()->getParent()->getDataLayout();
+  bool Change = false;
+  for (PHINode *&PHI : Worklist) {
+    if (Value *Replacement = simplifyInstruction(PHI, DL)) {
+      PHI->replaceAllUsesWith(Replacement);
+      PHI->eraseFromParent();
+      PHI = nullptr; // Mark as removed
+      Change = true;
+    }
+  }
+  return Change;
+}
+
+bool SSAUpdaterBulk::deduplicatePass(const SmallVectorImpl<PHINode *> &Worklist,
+                                     SmallPtrSetImpl<PHINode *> &PHIToRemove) {
+
+  auto FindFirstNonPHIIt = [](BasicBlock *BB) {
+    PHINode *LastPHI = nullptr;
+    for (auto &PHI : BB->phis())
+      LastPHI = &PHI;
+    assert(LastPHI);
+    return std::next(LastPHI->getIterator());
+  };
+
+  // BB -> First BB's Non-PHI iterator map
+  SmallDenseMap<BasicBlock *, BasicBlock::iterator> Blocks;
+  // Reverse Worklist to preserve the order of new phis.
+  for (PHINode *PHI : reverse(Worklist)) {
+    if (!PHI)
+      continue;
+    auto *BB = PHI->getParent();
+    auto [I, Inserted] = Blocks.try_emplace(BB);
+    if (Inserted)
+      I->second = FindFirstNonPHIIt(BB);
+
+    // Move newly inserted PHIs to the end to ensure that
+    // EliminateDuplicatePHINodes prioritizes removing the newly created PHIs
+    // over the existing ones, preserving the original PHI nodes.
+    PHI->moveBefore(I->second);
+  }
+
+  for (auto [BB, I] : Blocks)
+    EliminateDuplicatePHINodes(BB, PHIToRemove);
+
+  for (PHINode *PHI : PHIToRemove)
+    PHI->eraseFromParent();
+
+  return !PHIToRemove.empty();
+}
+
+void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
+                                    SmallVectorImpl<PHINode *> *InsertedPHIs) {
+  SmallVector<PHINode *, 4> PHIs;
+  createPHIsAndRewrite(DT, PHIs);
+  simplifyPass(PHIs);
+
+  SmallPtrSet<PHINode *, 8> PHIToRemove;
+  deduplicatePass(PHIs, PHIToRemove);
+
+  if (!InsertedPHIs)
+    return;
+
+  for (auto *&PHI : PHIs)
+    if (PHI && PHIToRemove.count(PHI))
+      PHI = nullptr; // Mark as removed.
----------------
nikic wrote:

I feel like this look belongs into deduplicatePass.

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


More information about the llvm-commits mailing list