diff options
author | Michael Gottesman <mgottesman@apple.com> | 2015-03-06 00:34:39 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2015-03-06 00:34:39 +0000 |
commit | 4eae396ae9eb37ad4e7f5648069110d6a08f5f52 (patch) | |
tree | d4c5d4d3e0887693dca0247317fac93dc70e7a7e /llvm/lib/Transforms/ObjCARC/PtrState.cpp | |
parent | feb138e211406a4da10b77c1a47faca0aa8c5517 (diff) | |
download | bcm5719-llvm-4eae396ae9eb37ad4e7f5648069110d6a08f5f52.tar.gz bcm5719-llvm-4eae396ae9eb37ad4e7f5648069110d6a08f5f52.zip |
[objc-arc] Refactor (Re-)initialization of PtrState from dataflow -> {TopDown,BottomUp}PtrState Class.
This initialization occurs when we see a new retain or release. Before
we performed the actual initialization inline in the dataflow. That is
just messy.
llvm-svn: 231438
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC/PtrState.cpp')
-rw-r--r-- | llvm/lib/Transforms/ObjCARC/PtrState.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index 2b647689368..db4a81650e4 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp +++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp @@ -10,6 +10,7 @@ #define DEBUG_TYPE "objc-arc-ptr-state" #include "llvm/Support/Debug.h" #include "PtrState.h" +#include "ObjCARC.h" using namespace llvm; using namespace llvm::objcarc; @@ -137,3 +138,53 @@ void PtrState::Merge(const PtrState &Other, bool TopDown) { Partial = RRI.Merge(Other.RRI); } } + +bool BottomUpPtrState::InitBottomUp(ARCMDKindCache &Cache, Instruction *I) { + // If we see two releases in a row on the same pointer. If so, make + // a note, and we'll cicle back to revisit it after we've + // hopefully eliminated the second release, which may allow us to + // eliminate the first release too. + // Theoretically we could implement removal of nested retain+release + // pairs by making PtrState hold a stack of states, but this is + // simple and avoids adding overhead for the non-nested case. + bool NestingDetected = false; + if (GetSeq() == S_Release || GetSeq() == S_MovableRelease) { + DEBUG(dbgs() << "Found nested releases (i.e. a release pair)\n"); + NestingDetected = true; + } + + MDNode *ReleaseMetadata = I->getMetadata(Cache.ImpreciseReleaseMDKind); + Sequence NewSeq = ReleaseMetadata ? S_MovableRelease : S_Release; + ResetSequenceProgress(NewSeq); + SetReleaseMetadata(ReleaseMetadata); + SetKnownSafe(HasKnownPositiveRefCount()); + SetTailCallRelease(cast<CallInst>(I)->isTailCall()); + InsertCall(I); + SetKnownPositiveRefCount(); + return NestingDetected; +} + +bool TopDownPtrState::InitTopDown(ARCInstKind Kind, Instruction *I) { + bool NestingDetected = false; + // Don't do retain+release tracking for ARCInstKind::RetainRV, because + // it's + // better to let it remain as the first instruction after a call. + if (Kind != ARCInstKind::RetainRV) { + // If we see two retains in a row on the same pointer. If so, make + // a note, and we'll cicle back to revisit it after we've + // hopefully eliminated the second retain, which may allow us to + // eliminate the first retain too. + // Theoretically we could implement removal of nested retain+release + // pairs by making PtrState hold a stack of states, but this is + // simple and avoids adding overhead for the non-nested case. + if (GetSeq() == S_Retain) + NestingDetected = true; + + ResetSequenceProgress(S_Retain); + SetKnownSafe(HasKnownPositiveRefCount()); + InsertCall(I); + } + + SetKnownPositiveRefCount(); + return NestingDetected; +} |