diff options
Diffstat (limited to 'lib/Transforms/Utils')
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 41 | ||||
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 49 |
2 files changed, 38 insertions, 52 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index 864b6ba3db..17628e2253 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -177,38 +177,13 @@ bool InlineFunction(CallSite CS) { // If we just inlined a call due to an invoke instruction, scan the inlined // function checking for function calls that should now be made into invoke - // instructions, and for llvm.exc.rethrow()'s which should be turned into - // branches. + // instructions, and for unwind's which should be turned into branches. if (InvokeDest) - for (Function::iterator BB = LastBlock, E = Caller->end(); BB != E; ++BB) + for (Function::iterator BB = LastBlock, E = Caller->end(); BB != E; ++BB) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { // We only need to check for function calls: inlined invoke instructions // require no special handling... if (CallInst *CI = dyn_cast<CallInst>(I)) { - if (Function *F = CI->getCalledFunction()) - if (unsigned ID = F->getIntrinsicID()) - if (ID == LLVMIntrinsic::unwind) { - // llvm.unwind requires special handling when it gets inlined - // into an invoke site. Once this happens, we know that the - // unwind would cause a control transfer to the invoke exception - // destination, so we can transform it into a direct branch to - // the exception destination. - BranchInst *BI = new BranchInst(InvokeDest, CI); - - // Note that since any instructions after the rethrow/branch are - // dead, we must delete them now (otherwise the terminator we - // just inserted wouldn't be at the end of the basic block!) - BasicBlock *CurBB = BB; - while (&CurBB->back() != BI) { - Instruction *I = &CurBB->back(); - if (!I->use_empty()) - I->replaceAllUsesWith(Constant::getNullValue(I->getType())); - CurBB->getInstList().pop_back(); - } - - break; // Done with this basic block! - } - // Convert this function call into an invoke instruction... // First, split the basic block... @@ -231,6 +206,18 @@ bool InlineFunction(CallSite CS) { } } + if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) { + // An UnwindInst requires special handling when it gets inlined into an + // invoke site. Once this happens, we know that the unwind would cause + // a control transfer to the invoke exception destination, so we can + // transform it into a direct branch to the exception destination. + BranchInst *BI = new BranchInst(InvokeDest, UI); + + // Delete the unwind instruction! + UI->getParent()->getInstList().pop_back(); + } + } + // Now that the function is correct, make it a little bit nicer. In // particular, move the basic blocks inserted from the end of the function // into the space made by splitting the source basic block. diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index f47c840518..1d5e4ec8af 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -101,32 +101,31 @@ bool SimplifyCFG(BasicBlock *BB) { // 'llvm.unwind'. If so, replace any invoke instructions which use this as an // exception destination with call instructions. // - if (CallInst *CI = dyn_cast<CallInst>(&BB->front())) - if (Function *F = CI->getCalledFunction()) - if (F->getIntrinsicID() == LLVMIntrinsic::unwind) { - std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB)); - while (!Preds.empty()) { - BasicBlock *Pred = Preds.back(); - if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator())) - if (II->getExceptionalDest() == BB) { - // Insert a new branch instruction before the invoke, because this - // is now a fall through... - BranchInst *BI = new BranchInst(II->getNormalDest(), II); - Pred->getInstList().remove(II); // Take out of symbol table - - // Insert the call now... - std::vector<Value*> Args(II->op_begin()+3, II->op_end()); - CallInst *CI = new CallInst(II->getCalledValue(), Args, - II->getName(), BI); - // If the invoke produced a value, the Call now does instead - II->replaceAllUsesWith(CI); - delete II; - Changed = true; - } - - Preds.pop_back(); - } + if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) + if (BB->begin() == BasicBlock::iterator(UI)) { // Empty block? + std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB)); + while (!Preds.empty()) { + BasicBlock *Pred = Preds.back(); + if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator())) + if (II->getExceptionalDest() == BB) { + // Insert a new branch instruction before the invoke, because this + // is now a fall through... + BranchInst *BI = new BranchInst(II->getNormalDest(), II); + Pred->getInstList().remove(II); // Take out of symbol table + + // Insert the call now... + std::vector<Value*> Args(II->op_begin()+3, II->op_end()); + CallInst *CI = new CallInst(II->getCalledValue(), Args, + II->getName(), BI); + // If the invoke produced a value, the Call now does instead + II->replaceAllUsesWith(CI); + delete II; + Changed = true; + } + + Preds.pop_back(); } + } // Remove basic blocks that have no predecessors... which are unreachable. if (pred_begin(BB) == pred_end(BB) && |