From f7e54dce1007dd858a14867a51c9986dac431969 Mon Sep 17 00:00:00 2001 From: Frits van Bommel Date: Mon, 4 May 2009 12:08:30 +0200 Subject: [PATCH] Don't forget to update the control flow when deleting an invoke. Fixes #284. --- gen/passes/GarbageCollect2Stack.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/gen/passes/GarbageCollect2Stack.cpp b/gen/passes/GarbageCollect2Stack.cpp index 1be5f879..d8f974c8 100644 --- a/gen/passes/GarbageCollect2Stack.cpp +++ b/gen/passes/GarbageCollect2Stack.cpp @@ -96,6 +96,21 @@ bool GarbageCollect2Stack::doInitialization(Module &M) { KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true); } +static void RemoveCall(Instruction* Inst) { + if (InvokeInst* Invoke = dyn_cast(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 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) { if (Inst->use_empty() && info->SafeToDelete) { Changed = true; NumDeleted++; - Inst->eraseFromParent(); + RemoveCall(Inst); continue; } @@ -218,17 +233,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) { newVal = Builder.CreateBitCast(newVal, Inst->getType()); Inst->replaceAllUsesWith(newVal); - // If this was an invoke instruction, update the control flow. - if (InvokeInst* Invoke = dyn_cast(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); } }