OSDN Git Service

[objc-arc] Refactor (Re-)initialization of PtrState from dataflow -> {TopDown,BottomU...
authorMichael Gottesman <mgottesman@apple.com>
Fri, 6 Mar 2015 00:34:39 +0000 (00:34 +0000)
committerMichael Gottesman <mgottesman@apple.com>
Fri, 6 Mar 2015 00:34:39 +0000 (00:34 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231438 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/ObjCARC/ObjCARCOpts.cpp
lib/Transforms/ObjCARC/PtrState.cpp
lib/Transforms/ObjCARC/PtrState.h

index 6884626..33f09ac 100644 (file)
@@ -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<CallInst>(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;
index 2b64768..db4a816 100644 (file)
@@ -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;
+}
index d49c909..299acff 100644 (file)
@@ -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