Update the callgraph when replacing InvokeInst with CallInst when inlining.
authorNick Lewycky <nicholas@mxc.ca>
Tue, 3 Feb 2009 04:34:40 +0000 (04:34 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Tue, 3 Feb 2009 04:34:40 +0000 (04:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63600 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/InlineFunction.cpp
test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll [new file with mode: 0644]

index cee224aae52400ff9b6727ff40068ed053e9c66a..eb136b503497255943399cc8de1e346a684abd0b 100644 (file)
@@ -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 (file)
index 0000000..38d7596
--- /dev/null
@@ -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()