diff options
author | Dan Gohman <gohman@apple.com> | 2011-06-16 20:57:14 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2011-06-16 20:57:14 +0000 |
commit | 00fa9634d59fc844d51376d2efd2780ddd37ff6a (patch) | |
tree | 8845b2e45e3a8f8a5c5515f00346671d6cb03d40 /llvm/lib/Transforms | |
parent | 5964a0154b1b97b96e72368fa761228b906cabf4 (diff) | |
download | bcm5719-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')
-rw-r--r-- | llvm/lib/Transforms/Scalar/ObjCARC.cpp | 37 |
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. |