From 4eae396ae9eb37ad4e7f5648069110d6a08f5f52 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Fri, 6 Mar 2015 00:34:39 +0000 Subject: [PATCH] [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 --- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 47 ++------------------------ llvm/lib/Transforms/ObjCARC/PtrState.cpp | 51 +++++++++++++++++++++++++++++ llvm/lib/Transforms/ObjCARC/PtrState.h | 13 ++++++-- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 6884626..33f09ac 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -1048,28 +1048,7 @@ bool ObjCARCOpt::VisitInstructionBottomUp( Arg = GetArgRCIdentityRoot(Inst); BottomUpPtrState &S = MyStates.getPtrBottomUpState(Arg); - - // 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. - if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease) { - DEBUG(dbgs() << "Found nested releases (i.e. a release pair)\n"); - NestingDetected = true; - } - - MDNode *ReleaseMetadata = - Inst->getMetadata(MDKindCache.ImpreciseReleaseMDKind); - Sequence NewSeq = ReleaseMetadata ? S_MovableRelease : S_Release; - S.ResetSequenceProgress(NewSeq); - S.SetReleaseMetadata(ReleaseMetadata); - S.SetKnownSafe(S.HasKnownPositiveRefCount()); - S.SetTailCallRelease(cast(Inst)->isTailCall()); - S.InsertCall(Inst); - S.SetKnownPositiveRefCount(); + NestingDetected |= S.InitBottomUp(MDKindCache, Inst); break; } case ARCInstKind::RetainBlock: @@ -1294,30 +1273,8 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, case ARCInstKind::Retain: case ARCInstKind::RetainRV: { Arg = GetArgRCIdentityRoot(Inst); - TopDownPtrState &S = MyStates.getPtrTopDownState(Arg); - - // 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 (Class != 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 (S.GetSeq() == S_Retain) - NestingDetected = true; - - S.ResetSequenceProgress(S_Retain); - S.SetKnownSafe(S.HasKnownPositiveRefCount()); - S.InsertCall(Inst); - } - - S.SetKnownPositiveRefCount(); - + NestingDetected |= S.InitTopDown(Class, Inst); // A retain can be a potential use; procede to the generic checking // code below. break; diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index 2b64768..db4a816 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(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; +} diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.h b/llvm/lib/Transforms/ObjCARC/PtrState.h index d49c909..299acff 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.h +++ b/llvm/lib/Transforms/ObjCARC/PtrState.h @@ -17,6 +17,7 @@ #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H #define LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H +#include "ARCInstKind.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Value.h" @@ -26,6 +27,8 @@ namespace llvm { namespace objcarc { +struct ARCMDKindCache; + /// \enum Sequence /// /// \brief A sequence of states that a pointer may go through in which an @@ -160,14 +163,20 @@ public: const RRInfo &GetRRInfo() const { return RRI; } }; -/// This is currently a stub. struct BottomUpPtrState : PtrState { BottomUpPtrState() : PtrState() {} + + /// (Re-)Initialize this bottom up pointer returning true if we detected a + /// pointer with nested releases. + bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I); }; -/// This is currently a stub. struct TopDownPtrState : PtrState { TopDownPtrState() : PtrState() {} + + /// (Re-)Initialize this bottom up pointer returning true if we detected a + /// pointer with nested releases. + bool InitTopDown(ARCInstKind Kind, Instruction *I); }; } // end namespace objcarc -- 2.7.4