diff options
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 11 | ||||
-rw-r--r-- | test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll | 32 |
2 files changed, 40 insertions, 3 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index cee224a..eb136b5 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -37,11 +37,12 @@ bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) { /// in the body of the inlined function into invokes and turn unwind /// instructions into branches to the invoke unwind dest. /// -/// II is the invoke instruction begin inlined. FirstNewBlock is the first +/// II is the invoke instruction being inlined. FirstNewBlock is the first /// block of the inlined code (the last block is the end of the function), /// and InlineCodeInfo is information about the code that got inlined. static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, - ClonedCodeInfo &InlinedCodeInfo) { + ClonedCodeInfo &InlinedCodeInfo, + CallGraph *CG) { BasicBlock *InvokeDest = II->getUnwindDest(); std::vector<Value*> InvokeDestPHIValues; @@ -93,6 +94,10 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, // Make sure that anything using the call now uses the invoke! CI->replaceAllUsesWith(II); + // Update the callgraph. + if (CG) + (*CG)[Caller]->replaceCallSite(CI, II); + // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); Split->getInstList().pop_front(); // Delete the original call @@ -433,7 +438,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) { // any inlined 'unwind' instructions into branches to the invoke exception // destination, and call instructions into invoke instructions. if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) - HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo); + HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo, CG); // If we cloned in _exactly one_ basic block, and if that block ends in a // return instruction, we splice the body of the inlined callee directly into diff --git a/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll b/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll new file mode 100644 index 0000000..38d7596 --- /dev/null +++ b/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | opt -inline -prune-eh +; PR3367 + +define void @f2() { + invoke void @f6() + to label %ok1 unwind label %lpad1 + +ok1: + ret void + +lpad1: + invoke void @f4() + to label %ok2 unwind label %lpad2 + +ok2: + call void @f8() + unreachable + +lpad2: + unreachable +} + +declare void @f3() + +define void @f4() { + call void @f3() + ret void +} + +declare void @f6() nounwind + +declare void @f8() |