From 6080596328e6d37e170115214d33523f2b7c4846 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Fri, 6 Mar 2015 00:34:42 +0000 Subject: [PATCH] [objc-arc] Move the checking of whether or not we can match onto PtrStates and out of the main dataflow. These refactored computations check whether or not we are at a stage of the sequence where we can perform a match. This patch moves the computation out of the main dataflow and into {BottomUp,TopDown}PtrState. llvm-svn: 231439 --- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 64 ++++++----------------------- llvm/lib/Transforms/ObjCARC/PtrState.cpp | 50 ++++++++++++++++++++++ llvm/lib/Transforms/ObjCARC/PtrState.h | 13 ++++++ 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 33f09ac..a9e956b 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -1059,33 +1059,13 @@ bool ObjCARCOpt::VisitInstructionBottomUp( case ARCInstKind::Retain: case ARCInstKind::RetainRV: { Arg = GetArgRCIdentityRoot(Inst); - BottomUpPtrState &S = MyStates.getPtrBottomUpState(Arg); - S.SetKnownPositiveRefCount(); - - Sequence OldSeq = S.GetSeq(); - switch (OldSeq) { - case S_Stop: - case S_Release: - case S_MovableRelease: - case S_Use: - // If OldSeq is not S_Use or OldSeq is S_Use and we are tracking an - // imprecise release, clear our reverse insertion points. - if (OldSeq != S_Use || S.IsTrackingImpreciseReleases()) - S.ClearReverseInsertPts(); - // FALL THROUGH - case S_CanRelease: - // 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 (S.MatchWithRetain()) { + // 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) Retains[Inst] = S.GetRRInfo(); S.ClearSequenceProgress(); - break; - case S_None: - break; - case S_Retain: - llvm_unreachable("bottom-up pointer in retain state!"); } // A retain moving bottom up can be a use. break; @@ -1268,7 +1248,8 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, case ARCInstKind::RetainBlock: // In OptimizeIndividualCalls, we have strength reduced all optimizable // objc_retainBlocks to objc_retains. Thus at this point any - // objc_retainBlocks that we see are not optimizable. + // objc_retainBlocks that we see are not optimizable. We need to break since + // a retain can be a potential use. break; case ARCInstKind::Retain: case ARCInstKind::RetainRV: { @@ -1281,44 +1262,25 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, } case ARCInstKind::Release: { Arg = GetArgRCIdentityRoot(Inst); - TopDownPtrState &S = MyStates.getPtrTopDownState(Arg); - S.ClearKnownPositiveRefCount(); - - Sequence OldSeq = S.GetSeq(); - - MDNode *ReleaseMetadata = - Inst->getMetadata(MDKindCache.ImpreciseReleaseMDKind); - - switch (OldSeq) { - case S_Retain: - case S_CanRelease: - if (OldSeq == S_Retain || ReleaseMetadata != nullptr) - S.ClearReverseInsertPts(); - // FALL THROUGH - case S_Use: - S.SetReleaseMetadata(ReleaseMetadata); - S.SetTailCallRelease(cast(Inst)->isTailCall()); + // Try to form a tentative pair in between this release instruction and the + // top down pointers that we are tracking. + if (S.MatchWithRelease(MDKindCache, Inst)) { + // If we succeed, copy S's RRInfo into the Release -> {Retain Set + // Map}. Then we clear S. Releases[Inst] = S.GetRRInfo(); S.ClearSequenceProgress(); - break; - case S_None: - break; - case S_Stop: - case S_Release: - case S_MovableRelease: - llvm_unreachable("top-down pointer in release state!"); } break; } case ARCInstKind::AutoreleasepoolPop: // Conservatively, clear MyStates for all known pointers. MyStates.clearTopDownPointers(); - return NestingDetected; + return false; case ARCInstKind::AutoreleasepoolPush: case ARCInstKind::None: - // These are irrelevant. - return NestingDetected; + // These can not be uses of + return false; default: break; } diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index db4a816..9a82f36c 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp +++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp @@ -164,6 +164,29 @@ bool BottomUpPtrState::InitBottomUp(ARCMDKindCache &Cache, Instruction *I) { return NestingDetected; } +bool BottomUpPtrState::MatchWithRetain() { + SetKnownPositiveRefCount(); + + Sequence OldSeq = GetSeq(); + switch (OldSeq) { + case S_Stop: + case S_Release: + case S_MovableRelease: + case S_Use: + // If OldSeq is not S_Use or OldSeq is S_Use and we are tracking an + // imprecise release, clear our reverse insertion points. + if (OldSeq != S_Use || IsTrackingImpreciseReleases()) + ClearReverseInsertPts(); + // FALL THROUGH + case S_CanRelease: + return true; + case S_None: + return false; + case S_Retain: + llvm_unreachable("bottom-up pointer in retain state!"); + } +} + bool TopDownPtrState::InitTopDown(ARCInstKind Kind, Instruction *I) { bool NestingDetected = false; // Don't do retain+release tracking for ARCInstKind::RetainRV, because @@ -188,3 +211,30 @@ bool TopDownPtrState::InitTopDown(ARCInstKind Kind, Instruction *I) { SetKnownPositiveRefCount(); return NestingDetected; } + +bool TopDownPtrState::MatchWithRelease(ARCMDKindCache &Cache, + Instruction *Release) { + ClearKnownPositiveRefCount(); + + Sequence OldSeq = GetSeq(); + + MDNode *ReleaseMetadata = Release->getMetadata(Cache.ImpreciseReleaseMDKind); + + switch (OldSeq) { + case S_Retain: + case S_CanRelease: + if (OldSeq == S_Retain || ReleaseMetadata != nullptr) + ClearReverseInsertPts(); + // FALL THROUGH + case S_Use: + SetReleaseMetadata(ReleaseMetadata); + SetTailCallRelease(cast(Release)->isTailCall()); + return true; + case S_None: + return false; + case S_Stop: + case S_Release: + case S_MovableRelease: + llvm_unreachable("top-down pointer in bottom up state!"); + } +} diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.h b/llvm/lib/Transforms/ObjCARC/PtrState.h index 299acff..49cf7c6 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.h +++ b/llvm/lib/Transforms/ObjCARC/PtrState.h @@ -169,6 +169,14 @@ struct BottomUpPtrState : PtrState { /// (Re-)Initialize this bottom up pointer returning true if we detected a /// pointer with nested releases. bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I); + + /// Return true if this set of releases can be paired with a release. Modifies + /// state appropriately to reflect that the matching occured if it is + /// successful. + /// + /// It is assumed that one has already checked that the RCIdentity of the + /// retain and the RCIdentity of this ptr state are the same. + bool MatchWithRetain(); }; struct TopDownPtrState : PtrState { @@ -177,6 +185,11 @@ struct TopDownPtrState : PtrState { /// (Re-)Initialize this bottom up pointer returning true if we detected a /// pointer with nested releases. bool InitTopDown(ARCInstKind Kind, Instruction *I); + + /// Return true if this set of retains can be paired with the given + /// release. Modifies state appropriately to reflect that the matching + /// occured. + bool MatchWithRelease(ARCMDKindCache &Cache, Instruction *Release); }; } // end namespace objcarc -- 2.7.4