summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/ObjCARC.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2011-06-16 20:57:14 +0000
committerDan Gohman <gohman@apple.com>2011-06-16 20:57:14 +0000
commit00fa9634d59fc844d51376d2efd2780ddd37ff6a (patch)
tree8845b2e45e3a8f8a5c5515f00346671d6cb03d40 /llvm/lib/Transforms/Scalar/ObjCARC.cpp
parent5964a0154b1b97b96e72368fa761228b906cabf4 (diff)
downloadbcm5719-llvm-00fa9634d59fc844d51376d2efd2780ddd37ff6a.tar.gz
bcm5719-llvm-00fa9634d59fc844d51376d2efd2780ddd37ff6a.zip
Fix ARCOpt to insert releases on both successors of an invoke rather
than trying to insert them immediately after the invoke. llvm-svn: 133188
Diffstat (limited to 'llvm/lib/Transforms/Scalar/ObjCARC.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/ObjCARC.cpp37
1 files changed, 27 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/ObjCARC.cpp b/llvm/lib/Transforms/Scalar/ObjCARC.cpp
index e65e2853c2a..6cd35e5c9e7 100644
--- a/llvm/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/llvm/lib/Transforms/Scalar/ObjCARC.cpp
@@ -2550,16 +2550,33 @@ void ObjCARCOpt::MoveCalls(Value *Arg,
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.
OpenPOWER on IntegriCloud