[llvm] 73d6a48 - [WinEH] Track changes in WinEHPrepare pass (#134121)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 30 06:29:35 PDT 2025


Author: Aaron Puchert
Date: 2025-05-30T15:29:32+02:00
New Revision: 73d6a48029d61e8a26749cd9990108357b5318b1

URL: https://github.com/llvm/llvm-project/commit/73d6a48029d61e8a26749cd9990108357b5318b1
DIFF: https://github.com/llvm/llvm-project/commit/73d6a48029d61e8a26749cd9990108357b5318b1.diff

LOG: [WinEH] Track changes in WinEHPrepare pass (#134121)

Before this change, the pass would always claim to have changed IR if
there is a scope-based personality function. We add some plumbing to
track if there was an actual change.

This should be NFC, except that we might now preserve more analysis
passes.

Added: 
    

Modified: 
    llvm/lib/CodeGen/WinEHPrepare.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 43dd651a686b9..66d29cb5d65e4 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -78,10 +78,10 @@ class WinEHPrepareImpl {
   bool prepareExplicitEH(Function &F);
   void colorFunclets(Function &F);
 
-  void demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly);
-  void cloneCommonBlocks(Function &F);
-  void removeImplausibleInstructions(Function &F);
-  void cleanupPreparedFunclets(Function &F);
+  bool demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly);
+  bool cloneCommonBlocks(Function &F);
+  bool removeImplausibleInstructions(Function &F);
+  bool cleanupPreparedFunclets(Function &F);
   void verifyPreparedFunclets(Function &F);
 
   bool DemoteCatchSwitchPHIOnly;
@@ -861,8 +861,10 @@ void WinEHPrepareImpl::colorFunclets(Function &F) {
   }
 }
 
-void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
+bool WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
                                             bool DemoteCatchSwitchPHIOnly) {
+  bool Changed = false;
+
   // Strip PHI nodes off of EH pads.
   SmallVector<PHINode *, 16> PHINodes;
   for (BasicBlock &BB : make_early_inc_range(F)) {
@@ -892,6 +894,8 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
           break;
       }
 
+      Changed = true;
+
       AllocaInst *SpillSlot = insertPHILoads(PN, F);
       if (SpillSlot)
         insertPHIStores(PN, SpillSlot);
@@ -905,9 +909,13 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
     PN->replaceAllUsesWith(PoisonValue::get(PN->getType()));
     PN->eraseFromParent();
   }
+
+  return Changed;
 }
 
-void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
+bool WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
+  bool Changed = false;
+
   // We need to clone all blocks which belong to multiple funclets.  Values are
   // remapped throughout the funclet to propagate both the new instructions
   // *and* the new basic blocks themselves.
@@ -952,6 +960,8 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
     if (Orig2Clone.empty())
       continue;
 
+    Changed = true;
+
     // Update our color mappings to reflect that one block has lost a color and
     // another has gained a color.
     for (auto &BBMapping : Orig2Clone) {
@@ -1107,9 +1117,13 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
         SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
     }
   }
+
+  return Changed;
 }
 
-void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
+bool WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
+  bool Changed = false;
+
   // Remove implausible terminators and replace them with UnreachableInst.
   for (auto &Funclet : FuncletBlocks) {
     BasicBlock *FuncletPadBB = Funclet.first;
@@ -1139,6 +1153,8 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
             (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
           continue;
 
+        Changed = true;
+
         // This call site was not part of this funclet, remove it.
         if (isa<InvokeInst>(CB)) {
           // Remove the unwind edge if it was an invoke.
@@ -1170,9 +1186,11 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
         IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
       if (IsUnreachableRet || IsUnreachableCatchret ||
           IsUnreachableCleanupret) {
+        Changed = true;
         changeToUnreachable(TI);
       } else if (isa<InvokeInst>(TI)) {
         if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
+          Changed = true;
           // Invokes within a cleanuppad for the MSVC++ personality never
           // transfer control to their unwind edge: the personality will
           // terminate the program.
@@ -1181,20 +1199,26 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
       }
     }
   }
+
+  return Changed;
 }
 
-void WinEHPrepareImpl::cleanupPreparedFunclets(Function &F) {
+bool WinEHPrepareImpl::cleanupPreparedFunclets(Function &F) {
+  bool Changed = false;
+
   // Clean-up some of the mess we made by removing useles PHI nodes, trivial
   // branches, etc.
   for (BasicBlock &BB : llvm::make_early_inc_range(F)) {
-    SimplifyInstructionsInBlock(&BB);
-    ConstantFoldTerminator(&BB, /*DeleteDeadConditions=*/true);
-    MergeBlockIntoPredecessor(&BB);
+    Changed |= SimplifyInstructionsInBlock(&BB);
+    Changed |= ConstantFoldTerminator(&BB, /*DeleteDeadConditions=*/true);
+    Changed |= MergeBlockIntoPredecessor(&BB);
   }
 
   // We might have some unreachable blocks after cleaning up some impossible
   // control flow.
-  removeUnreachableBlocks(F);
+  Changed |= removeUnreachableBlocks(F);
+
+  return Changed;
 }
 
 #ifndef NDEBUG
@@ -1216,23 +1240,23 @@ bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
   // Remove unreachable blocks.  It is not valuable to assign them a color and
   // their existence can trick us into thinking values are alive when they are
   // not.
-  removeUnreachableBlocks(F);
+  bool Changed = removeUnreachableBlocks(F);
 
   // Determine which blocks are reachable from which funclet entries.
   colorFunclets(F);
 
-  cloneCommonBlocks(F);
+  Changed |= cloneCommonBlocks(F);
 
   if (!DisableDemotion)
-    demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
-                                DemoteCatchSwitchPHIOnlyOpt);
+    Changed |= demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
+                                           DemoteCatchSwitchPHIOnlyOpt);
 
   if (!DisableCleanups) {
     assert(!verifyFunction(F, &dbgs()));
-    removeImplausibleInstructions(F);
+    Changed |= removeImplausibleInstructions(F);
 
     assert(!verifyFunction(F, &dbgs()));
-    cleanupPreparedFunclets(F);
+    Changed |= cleanupPreparedFunclets(F);
   }
 
   LLVM_DEBUG(verifyPreparedFunclets(F));
@@ -1240,7 +1264,7 @@ bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
   LLVM_DEBUG(colorFunclets(F));
   LLVM_DEBUG(verifyPreparedFunclets(F));
 
-  return true;
+  return Changed;
 }
 
 // TODO: Share loads when one use dominates another, or when a catchpad exit


        


More information about the llvm-commits mailing list