changeset 1298:7e303f9f16c7

Don't forget to update the control flow when deleting an invoke. Fixes #284.
author Frits van Bommel <fvbommel wxs.nl>
date Mon, 04 May 2009 12:08:30 +0200
parents 8e8552601ecd
children 847b767b2d0b
files gen/passes/GarbageCollect2Stack.cpp
diffstat 1 files changed, 17 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/gen/passes/GarbageCollect2Stack.cpp	Sun May 03 18:01:45 2009 +0200
+++ b/gen/passes/GarbageCollect2Stack.cpp	Mon May 04 12:08:30 2009 +0200
@@ -96,6 +96,21 @@
     KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true);
 }
 
+static void RemoveCall(Instruction* Inst) {
+    if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) {
+        // If this was an invoke instruction, we need to do some extra
+        // work to preserve the control flow.
+        
+        // First notify the exception landing pad block that we won't be
+        // going there anymore.
+        Invoke->getUnwindDest()->removePredecessor(Invoke->getParent());
+        // Create a branch to the "normal" destination.
+        BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent());
+    }
+    // Remove the runtime call.
+    Inst->eraseFromParent();
+}
+
 /// runOnFunction - Top level algorithm.
 ///
 bool GarbageCollect2Stack::runOnFunction(Function &F) {
@@ -146,7 +161,7 @@
             if (Inst->use_empty() && info->SafeToDelete) {
                 Changed = true;
                 NumDeleted++;
-                Inst->eraseFromParent();
+                RemoveCall(Inst);
                 continue;
             }
             
@@ -218,17 +233,7 @@
                 newVal = Builder.CreateBitCast(newVal, Inst->getType());
             Inst->replaceAllUsesWith(newVal);
             
-            // If this was an invoke instruction, update the control flow.
-            if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) {
-                // Notify the exception landing pad block that we won't be
-                // going there anymore.
-                Invoke->getUnwindDest()->removePredecessor(Invoke->getParent());
-                // Create a branch to the "normal" destination.
-                BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent());
-            }
-            
-            // Finally, remove the runtime call.
-            Inst->eraseFromParent();
+            RemoveCall(Inst);
         }
     }