X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FObjCARC%2FObjCARCOpts.cpp;h=48fe7c1440395f3fd4dec3c27b062f104a82c9ec;hb=722b0a4d293b16eebaed94ae65d5f11743cbcea5;hp=a66771a479b9a7c8545350e2d7cb733fe6ee4baa;hpb=817ef2d78e9ea9671ebd50913f9a0baf3ad70d93;p=oota-llvm.git diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index a66771a479b..48fe7c14403 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -469,9 +469,6 @@ namespace { /// occured, false otherwise. bool Merge(const RRInfo &Other); - bool IsTrackingImpreciseReleases() { - return ReleaseMetadata != 0; - } }; } @@ -521,15 +518,50 @@ namespace { /// The current position in the sequence. Sequence Seq : 8; - public: /// Unidirectional information about the current sequence. - /// - /// TODO: Encapsulate this better. RRInfo RRI; + public: PtrState() : KnownPositiveRefCount(false), Partial(false), Seq(S_None) {} + + bool IsKnownSafe() const { + return RRI.KnownSafe; + } + + void SetKnownSafe(const bool NewValue) { + RRI.KnownSafe = NewValue; + } + + bool IsTailCallRelease() const { + return RRI.IsTailCallRelease; + } + + void SetTailCallRelease(const bool NewValue) { + RRI.IsTailCallRelease = NewValue; + } + + bool IsTrackingImpreciseReleases() const { + return RRI.ReleaseMetadata != 0; + } + + const MDNode *GetReleaseMetadata() const { + return RRI.ReleaseMetadata; + } + + void SetReleaseMetadata(MDNode *NewValue) { + RRI.ReleaseMetadata = NewValue; + } + + bool IsCFGHazardAfflicted() const { + return RRI.CFGHazardAfflicted; + } + + void SetCFGHazardAfflicted(const bool NewValue) { + RRI.CFGHazardAfflicted = NewValue; + } + void SetKnownPositiveRefCount() { DEBUG(dbgs() << "Setting Known Positive.\n"); KnownPositiveRefCount = true; @@ -565,13 +597,33 @@ namespace { } void Merge(const PtrState &Other, bool TopDown); + + void InsertCall(Instruction *I) { + RRI.Calls.insert(I); + } + + void InsertReverseInsertPt(Instruction *I) { + RRI.ReverseInsertPts.insert(I); + } + + void ClearReverseInsertPts() { + RRI.ReverseInsertPts.clear(); + } + + bool HasReverseInsertPts() const { + return !RRI.ReverseInsertPts.empty(); + } + + const RRInfo &GetRRInfo() const { + return RRI; + } }; } void PtrState::Merge(const PtrState &Other, bool TopDown) { Seq = MergeSeqs(Seq, Other.Seq, TopDown); - KnownPositiveRefCount = KnownPositiveRefCount && Other.KnownPositiveRefCount; + KnownPositiveRefCount &= Other.KnownPositiveRefCount; // If we're not in a sequence (anymore), drop all associated state. if (Seq == S_None) { @@ -584,6 +636,10 @@ PtrState::Merge(const PtrState &Other, bool TopDown) { // mixing them is unsafe. ClearSequenceProgress(); } else { + // Otherwise merge the other PtrState's RRInfo into our RRInfo. At this + // point, we know that currently we are not partial. Stash whether or not + // the merge operation caused us to undergo a partial merging of reverse + // insertion points. Partial = RRI.Merge(Other.RRI); } } @@ -1719,11 +1775,11 @@ static void CheckForUseCFGHazard(const Sequence SuccSSeq, bool &ShouldContinue) { switch (SuccSSeq) { case S_CanRelease: { - if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe) { + if (!S.IsKnownSafe() && !SuccSRRIKnownSafe) { S.ClearSequenceProgress(); break; } - S.RRI.CFGHazardAfflicted = true; + S.SetCFGHazardAfflicted(true); ShouldContinue = true; break; } @@ -1733,7 +1789,7 @@ static void CheckForUseCFGHazard(const Sequence SuccSSeq, case S_Stop: case S_Release: case S_MovableRelease: - if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe) + if (!S.IsKnownSafe() && !SuccSRRIKnownSafe) AllSuccsHaveSame = false; else NotAllSeqEqualButKnownSafe = true; @@ -1762,7 +1818,7 @@ static void CheckForCanReleaseCFGHazard(const Sequence SuccSSeq, case S_Release: case S_MovableRelease: case S_Use: - if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe) + if (!S.IsKnownSafe() && !SuccSRRIKnownSafe) AllSuccsHaveSame = false; else NotAllSeqEqualButKnownSafe = true; @@ -1826,7 +1882,7 @@ ObjCARCOpt::CheckForCFGHazards(const BasicBlock *BB, // If we have S_Use or S_CanRelease, perform our check for cfg hazard // checks. - const bool SuccSRRIKnownSafe = SuccS.RRI.KnownSafe; + const bool SuccSRRIKnownSafe = SuccS.IsKnownSafe(); // *NOTE* We do not use Seq from above here since we are allowing for // S.GetSeq() to change while we are visiting basic blocks. @@ -1865,7 +1921,7 @@ ObjCARCOpt::CheckForCFGHazards(const BasicBlock *BB, // safe, stop code motion. This is because whether or not it is safe to // remove RR pairs via KnownSafe is an orthogonal concept to whether we // are allowed to perform code motion. - S.RRI.CFGHazardAfflicted = true; + S.SetCFGHazardAfflicted(true); } } } @@ -1903,10 +1959,10 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst, Sequence NewSeq = ReleaseMetadata ? S_MovableRelease : S_Release; ANNOTATE_BOTTOMUP(Inst, Arg, S.GetSeq(), NewSeq); S.ResetSequenceProgress(NewSeq); - S.RRI.ReleaseMetadata = ReleaseMetadata; - S.RRI.KnownSafe = S.HasKnownPositiveRefCount(); - S.RRI.IsTailCallRelease = cast(Inst)->isTailCall(); - S.RRI.Calls.insert(Inst); + S.SetReleaseMetadata(ReleaseMetadata); + S.SetKnownSafe(S.HasKnownPositiveRefCount()); + S.SetTailCallRelease(cast(Inst)->isTailCall()); + S.InsertCall(Inst); S.SetKnownPositiveRefCount(); break; } @@ -1930,14 +1986,14 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst, 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.RRI.IsTrackingImpreciseReleases()) - S.RRI.ReverseInsertPts.clear(); + if (OldSeq != S_Use || S.IsTrackingImpreciseReleases()) + S.ClearReverseInsertPts(); // FALL THROUGH case S_CanRelease: // Don't do retain+release tracking for IC_RetainRV, because it's // better to let it remain as the first instruction after a call. if (Class != IC_RetainRV) - Retains[Inst] = S.RRI; + Retains[Inst] = S.GetRRInfo(); S.ClearSequenceProgress(); break; case S_None: @@ -2021,14 +2077,14 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst, if (CanUse(Inst, Ptr, PA, Class)) { DEBUG(dbgs() << "CanUse: Seq: " << Seq << "; " << *Ptr << "\n"); - assert(S.RRI.ReverseInsertPts.empty()); + assert(!S.HasReverseInsertPts()); // If this is an invoke instruction, we're scanning it as part of // one of its successor blocks, since we can't insert code after it // in its own block, and we don't want to split critical edges. if (isa(Inst)) - S.RRI.ReverseInsertPts.insert(BB->getFirstInsertionPt()); + S.InsertReverseInsertPt(BB->getFirstInsertionPt()); else - S.RRI.ReverseInsertPts.insert(llvm::next(BasicBlock::iterator(Inst))); + S.InsertReverseInsertPt(llvm::next(BasicBlock::iterator(Inst))); S.SetSeq(S_Use); ANNOTATE_BOTTOMUP(Inst, Ptr, Seq, S_Use); } else if (Seq == S_Release && IsUser(Class)) { @@ -2037,12 +2093,12 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst, // Non-movable releases depend on any possible objc pointer use. S.SetSeq(S_Stop); ANNOTATE_BOTTOMUP(Inst, Ptr, S_Release, S_Stop); - assert(S.RRI.ReverseInsertPts.empty()); + assert(!S.HasReverseInsertPts()); // As above; handle invoke specially. if (isa(Inst)) - S.RRI.ReverseInsertPts.insert(BB->getFirstInsertionPt()); + S.InsertReverseInsertPt(BB->getFirstInsertionPt()); else - S.RRI.ReverseInsertPts.insert(llvm::next(BasicBlock::iterator(Inst))); + S.InsertReverseInsertPt(llvm::next(BasicBlock::iterator(Inst))); } break; case S_Stop: @@ -2162,8 +2218,8 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, ANNOTATE_TOPDOWN(Inst, Arg, S.GetSeq(), S_Retain); S.ResetSequenceProgress(S_Retain); - S.RRI.KnownSafe = S.HasKnownPositiveRefCount(); - S.RRI.Calls.insert(Inst); + S.SetKnownSafe(S.HasKnownPositiveRefCount()); + S.InsertCall(Inst); } S.SetKnownPositiveRefCount(); @@ -2186,12 +2242,12 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, case S_Retain: case S_CanRelease: if (OldSeq == S_Retain || ReleaseMetadata != 0) - S.RRI.ReverseInsertPts.clear(); + S.ClearReverseInsertPts(); // FALL THROUGH case S_Use: - S.RRI.ReleaseMetadata = ReleaseMetadata; - S.RRI.IsTailCallRelease = cast(Inst)->isTailCall(); - Releases[Inst] = S.RRI; + S.SetReleaseMetadata(ReleaseMetadata); + S.SetTailCallRelease(cast(Inst)->isTailCall()); + Releases[Inst] = S.GetRRInfo(); ANNOTATE_TOPDOWN(Inst, Arg, S.GetSeq(), S_None); S.ClearSequenceProgress(); break; @@ -2235,8 +2291,8 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, case S_Retain: S.SetSeq(S_CanRelease); ANNOTATE_TOPDOWN(Inst, Ptr, Seq, S_CanRelease); - assert(S.RRI.ReverseInsertPts.empty()); - S.RRI.ReverseInsertPts.insert(Inst); + assert(!S.HasReverseInsertPts()); + S.InsertReverseInsertPt(Inst); // One call can't cause a transition from S_Retain to S_CanRelease // and S_CanRelease to S_Use. If we've made the first transition,