[llvm-commits] [llvm] r133188 - in /llvm/trunk: lib/Transforms/Scalar/ObjCARC.cpp test/Transforms/ObjCARC/invoke.ll
Dan Gohman
gohman at apple.com
Thu Jun 16 13:57:14 PDT 2011
Author: djg
Date: Thu Jun 16 15:57:14 2011
New Revision: 133188
URL: http://llvm.org/viewvc/llvm-project?rev=133188&view=rev
Log:
Fix ARCOpt to insert releases on both successors of an invoke rather
than trying to insert them immediately after the invoke.
Added:
llvm/trunk/test/Transforms/ObjCARC/invoke.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=133188&r1=133187&r2=133188&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Thu Jun 16 15:57:14 2011
@@ -2550,16 +2550,33 @@
for (SmallPtrSet<Instruction *, 2>::const_iterator
PI = RetainsToMove.ReverseInsertPts.begin(),
PE = RetainsToMove.ReverseInsertPts.end(); PI != PE; ++PI) {
- Instruction *InsertPt = llvm::next(BasicBlock::iterator(*PI));
- Value *MyArg = ArgTy == ParamTy ? Arg :
- new BitCastInst(Arg, ParamTy, "", InsertPt);
- CallInst *Call = CallInst::Create(ReleaseFunc, MyArg, "", InsertPt);
- // Attach a clang.imprecise_release metadata tag, if appropriate.
- if (MDNode *M = ReleasesToMove.ReleaseMetadata)
- Call->setMetadata(ImpreciseReleaseMDKind, M);
- Call->setDoesNotThrow();
- if (ReleasesToMove.IsTailCallRelease)
- Call->setTailCall();
+ Instruction *LastUse = *PI;
+ Instruction *InsertPts[] = { 0, 0, 0 };
+ if (InvokeInst *II = dyn_cast<InvokeInst>(LastUse)) {
+ // We can't insert code immediately after an invoke instruction, so
+ // insert code at the beginning of both successor blocks instead.
+ // The invoke's return value isn't available in the unwind block,
+ // but our releases will never depend on it, because they must be
+ // paired with retains from before the invoke.
+ InsertPts[0] = II->getNormalDest()->getFirstNonPHI();
+ InsertPts[1] = II->getUnwindDest()->getFirstNonPHI();
+ } else {
+ // Insert code immediately after the last use.
+ InsertPts[0] = llvm::next(BasicBlock::iterator(LastUse));
+ }
+
+ for (Instruction **I = InsertPts; *I; ++I) {
+ Instruction *InsertPt = *I;
+ Value *MyArg = ArgTy == ParamTy ? Arg :
+ new BitCastInst(Arg, ParamTy, "", InsertPt);
+ CallInst *Call = CallInst::Create(ReleaseFunc, MyArg, "", InsertPt);
+ // Attach a clang.imprecise_release metadata tag, if appropriate.
+ if (MDNode *M = ReleasesToMove.ReleaseMetadata)
+ Call->setMetadata(ImpreciseReleaseMDKind, M);
+ Call->setDoesNotThrow();
+ if (ReleasesToMove.IsTailCallRelease)
+ Call->setTailCall();
+ }
}
// Delete the original retain and release calls.
Added: llvm/trunk/test/Transforms/ObjCARC/invoke.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjCARC/invoke.ll?rev=133188&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ObjCARC/invoke.ll (added)
+++ llvm/trunk/test/Transforms/ObjCARC/invoke.ll Thu Jun 16 15:57:14 2011
@@ -0,0 +1,67 @@
+; RUN: opt -S -objc-arc < %s | FileCheck %s
+
+declare i8* @objc_retain(i8*)
+declare void @objc_release(i8*)
+declare i8* @objc_msgSend(i8*, i8*, ...)
+declare void @use_pointer(i8*)
+declare void @callee()
+
+; ARCOpt shouldn't try to move the releases to the block containing the invoke.
+
+; CHECK: define void @test0(
+; CHECK: invoke.cont:
+; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+; CHECK: ret void
+; CHECK: lpad:
+; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+; CHECK: ret void
+define void @test0(i8* %zipFile) {
+entry:
+ call i8* @objc_retain(i8* %zipFile) nounwind
+ call void @use_pointer(i8* %zipFile)
+ invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %entry
+ call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+ ret void
+
+lpad: ; preds = %entry
+ call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; ARCOpt should move the release before the callee calls.
+
+; CHECK: define void @test1(
+; CHECK: invoke.cont:
+; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+; CHECK: call void @callee()
+; CHECK: br label %done
+; CHECK: lpad:
+; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+; CHECK: call void @callee()
+; CHECK: br label %done
+; CHECK: done:
+; CHECK-NEXT: ret void
+define void @test1(i8* %zipFile) {
+entry:
+ call i8* @objc_retain(i8* %zipFile) nounwind
+ call void @use_pointer(i8* %zipFile)
+ invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %entry
+ call void @callee()
+ br label %done
+
+lpad: ; preds = %entry
+ call void @callee()
+ br label %done
+
+done:
+ call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+!0 = metadata !{}
More information about the llvm-commits
mailing list