[llvm] [Transforms] Speed up SSAUpdater::FindExistingPHI (PR #100281)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 23 16:44:50 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: William Junda Huang (huangjd)

<details>
<summary>Changes</summary>

In SSAUpdater::FindExistingPHI, the cleanup function is inefficient for large function with many blocks because it clears the Phi value reference for every block if not matched for every phi value, even if most blocks are not modified by CheckIfPHIMatches. This behavior is particularly slow for large functions because the complexity is Θ(# PHI * # BBs).


Updated the behavior to only clear modified blocks, which in practice has a much less complexity because of early exit on PHI mismatch. 

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


1 Files Affected:

- (modified) llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h (+18-6) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
index 28ff6c4c7927d..24cbeaf72f82b 100644
--- a/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
+++ b/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -418,10 +418,6 @@ class SSAUpdaterImpl {
         RecordMatchingPHIs(BlockList);
         break;
       }
-      // Match failed: clear all the PHITag values.
-      for (typename BlockListTy::iterator I = BlockList->begin(),
-             E = BlockList->end(); I != E; ++I)
-        (*I)->PHITag = nullptr;
     }
   }
 
@@ -429,10 +425,21 @@ class SSAUpdaterImpl {
   /// in the BBMap.
   bool CheckIfPHIMatches(PhiT *PHI) {
     SmallVector<PhiT *, 20> WorkList;
+    SmallVector<BBInfo *, 20> TaggedBlocks;
     WorkList.push_back(PHI);
 
+    // Match failed: clear all the PHITag values. Only need to clear visited
+    // blocks.
+    auto OnFalseCleanup = [&]() {
+      for (BBInfo *TaggedBlock : TaggedBlocks) {
+        TaggedBlock->PHITag = nullptr;
+      }
+    };
+
     // Mark that the block containing this PHI has been visited.
-    BBMap[PHI->getParent()]->PHITag = PHI;
+    BBInfo *PHIBlock = BBMap[PHI->getParent()];
+    PHIBlock->PHITag = PHI;
+    TaggedBlocks.push_back(PHIBlock);
 
     while (!WorkList.empty()) {
       PHI = WorkList.pop_back_val();
@@ -450,21 +457,26 @@ class SSAUpdaterImpl {
         if (PredInfo->AvailableVal) {
           if (IncomingVal == PredInfo->AvailableVal)
             continue;
+          OnFalseCleanup();
           return false;
         }
 
         // Check if the value is a PHI in the correct block.
         PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
-        if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
+        if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB) {
+          OnFalseCleanup();
           return false;
+        }
 
         // If this block has already been visited, check if this PHI matches.
         if (PredInfo->PHITag) {
           if (IncomingPHIVal == PredInfo->PHITag)
             continue;
+          OnFalseCleanup();
           return false;
         }
         PredInfo->PHITag = IncomingPHIVal;
+        TaggedBlocks.push_back(PredInfo);
 
         WorkList.push_back(IncomingPHIVal);
       }

``````````

</details>


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


More information about the llvm-commits mailing list