From f7f1df48d40efe6eef0d15a804f651cbb4528ca3 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Sat, 31 Oct 2015 19:37:29 -0700 Subject: [PATCH] [loop-arc] Refactor code that processes how an instruction effects a reference count completely onto RefCountState. Previously, RefCountState provided APIs that the ARC dataflow used to determine if an instruction used, decremented, or guaranteed used a value that we are tracking. Upon further reflection, how an instruction affects a RefCountState is really internal to the RefCountState. rdar://22238729 --- lib/SILAnalysis/ARC/ARCRegionState.cpp | 58 +------------- .../ARC/GlobalARCSequenceDataflow.cpp | 58 +------------- lib/SILAnalysis/ARC/RefCountState.cpp | 66 +++++++++++++++ lib/SILAnalysis/ARC/RefCountState.h | 80 +++++++++++-------- 4 files changed, 116 insertions(+), 146 deletions(-) diff --git a/lib/SILAnalysis/ARC/ARCRegionState.cpp b/lib/SILAnalysis/ARC/ARCRegionState.cpp index 494b0264ecf7a..49fc795c3de82 100644 --- a/lib/SILAnalysis/ARC/ARCRegionState.cpp +++ b/lib/SILAnalysis/ARC/ARCRegionState.cpp @@ -212,34 +212,7 @@ bool ARCRegionState::processBlockBottomUp( if (Op && OtherState->first == Op) continue; - // If this state is not tracking anything, skip it. - if (!OtherState->second.isTrackingRefCount()) - continue; - - // Check if the instruction we are visiting could potentially use our - // instruction in a way that requires us to guarantee the lifetime of the - // pointer up to this point. This has the effect of performing a use and a - // decrement. - if (OtherState->second.handlePotentialGuaranteedUser(&I, InsertPt, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Check if the instruction we are visiting could potentially decrement - // the reference counted value we are tracking... in a manner that could - // cause us to change states. If we do change states continue... - if (OtherState->second.handlePotentialDecrement(&I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Otherwise check if the reference counted value we are tracking - // could be used by the given instruction. - if (OtherState->second.handlePotentialUser(&I, InsertPt, AA)) - DEBUG(llvm::dbgs() << " Found Potential Use:\n " - << OtherState->second.getRCRoot()); + OtherState->second.updateForSameLoopInst(&I, InsertPt, AA); } } @@ -330,34 +303,7 @@ bool ARCRegionState::processBlockTopDown( if (Op && OtherState->first == Op) continue; - // If the other state is not tracking anything, bail. - if (!OtherState->second.isTrackingRefCount()) - continue; - - // Check if the instruction we are visiting could potentially use our - // instruction in a way that requires us to guarantee the lifetime of the - // pointer up to this point. This has the effect of performing a use and a - // decrement. - if (OtherState->second.handlePotentialGuaranteedUser(&I, &I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Check if the instruction we are visiting could potentially decrement - // the reference counted value we are tracking in a manner that could - // cause us to change states. If we do change states continue... - if (OtherState->second.handlePotentialDecrement(&I, &I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Otherwise check if the reference counted value we are tracking - // could be used by the given instruction. - if (OtherState->second.handlePotentialUser(&I, AA)) - DEBUG(llvm::dbgs() << " Found Potential Use:\n " - << OtherState->second.getRCRoot()); + OtherState->second.updateForSameLoopInst(&I, &I, AA); } } diff --git a/lib/SILAnalysis/ARC/GlobalARCSequenceDataflow.cpp b/lib/SILAnalysis/ARC/GlobalARCSequenceDataflow.cpp index 970054192ee44..653ff97a1c29b 100644 --- a/lib/SILAnalysis/ARC/GlobalARCSequenceDataflow.cpp +++ b/lib/SILAnalysis/ARC/GlobalARCSequenceDataflow.cpp @@ -110,34 +110,7 @@ static bool processBBTopDown( if (Op && OtherState->first == Op) continue; - // If the other state is not tracking anything, bail. - if (!OtherState->second.isTrackingRefCount()) - continue; - - // Check if the instruction we are visiting could potentially use our - // instruction in a way that requires us to guarantee the lifetime of the - // pointer up to this point. This has the effect of performing a use and a - // decrement. - if (OtherState->second.handlePotentialGuaranteedUser(&I, &I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Check if the instruction we are visiting could potentially decrement - // the reference counted value we are tracking in a manner that could - // cause us to change states. If we do change states continue... - if (OtherState->second.handlePotentialDecrement(&I, &I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Otherwise check if the reference counted value we are tracking - // could be used by the given instruction. - if (OtherState->second.handlePotentialUser(&I, AA)) - DEBUG(llvm::dbgs() << " Found Potential Use:\n " - << OtherState->second.getRCRoot()); + OtherState->second.updateForSameLoopInst(&I, &I, AA); } } @@ -289,34 +262,7 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp( if (Op && OtherState->first == Op) continue; - // If this state is not tracking anything, skip it. - if (!OtherState->second.isTrackingRefCount()) - continue; - - // Check if the instruction we are visiting could potentially use our - // instruction in a way that requires us to guarantee the lifetime of the - // pointer up to this point. This has the effect of performing a use and a - // decrement. - if (OtherState->second.handlePotentialGuaranteedUser(&I, InsertPt, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Check if the instruction we are visiting could potentially decrement - // the reference counted value we are tracking... in a manner that could - // cause us to change states. If we do change states continue... - if (OtherState->second.handlePotentialDecrement(&I, AA)) { - DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " - << OtherState->second.getRCRoot()); - continue; - } - - // Otherwise check if the reference counted value we are tracking - // could be used by the given instruction. - if (OtherState->second.handlePotentialUser(&I, InsertPt, AA)) - DEBUG(llvm::dbgs() << " Found Potential Use:\n " - << OtherState->second.getRCRoot()); + OtherState->second.updateForSameLoopInst(&I, InsertPt, AA); } } diff --git a/lib/SILAnalysis/ARC/RefCountState.cpp b/lib/SILAnalysis/ARC/RefCountState.cpp index 1ccc69d3d4b0a..b157ef4cfb80c 100644 --- a/lib/SILAnalysis/ARC/RefCountState.cpp +++ b/lib/SILAnalysis/ARC/RefCountState.cpp @@ -428,6 +428,39 @@ bool BottomUpRefCountState::handlePotentialUser(SILInstruction *PotentialUser, return handleUser(PotentialUser, InsertPt, getRCRoot(), AA); } +void BottomUpRefCountState::updateForSameLoopInst(SILInstruction *I, + SILInstruction *InsertPt, + AliasAnalysis *AA) { + // If this state is not tracking anything, there is nothing to update. + if (!isTrackingRefCount()) + return; + + // Check if the instruction we are visiting could potentially use our + // instruction in a way that requires us to guarantee the lifetime of the + // pointer up to this point. This has the effect of performing a use and a + // decrement. + if (handlePotentialGuaranteedUser(I, InsertPt, AA)) { + DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " + << getRCRoot()); + return; + } + + // Check if the instruction we are visiting could potentially decrement + // the reference counted value we are tracking... in a manner that could + // cause us to change states. If we do change states continue... + if (handlePotentialDecrement(I, AA)) { + DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " + << getRCRoot()); + return; + } + + // Otherwise check if the reference counted value we are tracking + // could be used by the given instruction. + if (!handlePotentialUser(I, InsertPt, AA)) + return; + DEBUG(llvm::dbgs() << " Found Potential Use:\n " << getRCRoot()); +} + //===----------------------------------------------------------------------===// // Top Down Ref Count State //===----------------------------------------------------------------------===// @@ -765,6 +798,39 @@ bool TopDownRefCountState::handlePotentialUser(SILInstruction *PotentialUser, return handleUser(PotentialUser, getRCRoot(), AA); } +void TopDownRefCountState::updateForSameLoopInst(SILInstruction *I, + SILInstruction *InsertPt, + AliasAnalysis *AA) { + // If the other state is not tracking anything, bail. + if (!isTrackingRefCount()) + return; + + // Check if the instruction we are visiting could potentially use our + // instruction in a way that requires us to guarantee the lifetime of the + // pointer up to this point. This has the effect of performing a use and a + // decrement. + if (handlePotentialGuaranteedUser(I, InsertPt, AA)) { + DEBUG(llvm::dbgs() << " Found Potential Guaranteed Use:\n " + << getRCRoot()); + return; + } + + // Check if the instruction we are visiting could potentially decrement + // the reference counted value we are tracking in a manner that could + // cause us to change states. If we do change states continue... + if (handlePotentialDecrement(I, InsertPt, AA)) { + DEBUG(llvm::dbgs() << " Found Potential Decrement:\n " + << getRCRoot()); + return; + } + + // Otherwise check if the reference counted value we are tracking + // could be used by the given instruction. + if (!handlePotentialUser(I, AA)) + return; + DEBUG(llvm::dbgs() << " Found Potential Use:\n " << getRCRoot()); +} + //===----------------------------------------------------------------------===// // Printing Utilities //===----------------------------------------------------------------------===// diff --git a/lib/SILAnalysis/ARC/RefCountState.h b/lib/SILAnalysis/ARC/RefCountState.h index 970b1dd75d5f7..cf6d761488c36 100644 --- a/lib/SILAnalysis/ARC/RefCountState.h +++ b/lib/SILAnalysis/ARC/RefCountState.h @@ -202,23 +202,11 @@ class BottomUpRefCountState : public RefCountState { /// true. bool initWithMutatorInst(SILInstruction *I); - /// Check if PotentialDecrement can decrement the reference count associated - /// with the value we are tracking. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialDecrement(SILInstruction *Decrement, AliasAnalysis *AA); - - /// Check if PotentialUser could be a use of the reference counted value that - /// requires user to be alive. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialUser(SILInstruction *PotentialUser, - SILInstruction *InsertPt, AliasAnalysis *AA); - - /// Check if PotentialGuaranteedUser can use the reference count associated - /// with the value we are tracking. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialGuaranteedUser(SILInstruction *User, - SILInstruction *InsertPt, - AliasAnalysis *AA); + /// Update this reference count's state given the instruction \p I. \p + /// InsertPt is the point furthest up the CFG where we can move the currently + /// tracked reference count. + void updateForSameLoopInst(SILInstruction *I, SILInstruction *InsertPt, + AliasAnalysis *AA); /// Attempt to merge \p Other into this ref count state. Return true if we /// succeed and false otherwise. @@ -249,6 +237,11 @@ class BottomUpRefCountState : public RefCountState { /// advance return true. Otherwise return false. bool handleDecrement(SILInstruction *PotentialDecrement); + /// Check if PotentialDecrement can decrement the reference count associated + /// with the value we are tracking. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialDecrement(SILInstruction *Decrement, AliasAnalysis *AA); + /// Returns true if given the current lattice state, do we care if the value /// we are tracking is used. bool valueCanBeUsedGivenLatticeState() const; @@ -260,6 +253,12 @@ class BottomUpRefCountState : public RefCountState { bool handleUser(SILInstruction *PotentialUser, SILInstruction *InsertPt, SILValue RCIdentity, AliasAnalysis *AA); + /// Check if PotentialUser could be a use of the reference counted value that + /// requires user to be alive. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialUser(SILInstruction *PotentialUser, + SILInstruction *InsertPt, AliasAnalysis *AA); + /// Returns true if given the current lattice state, do we care if the value /// we are tracking is used. bool valueCanBeGuaranteedUsedGivenLatticeState() const; @@ -272,6 +271,13 @@ class BottomUpRefCountState : public RefCountState { SILInstruction *InsertPt, SILValue RCIdentity, AliasAnalysis *AA); + /// Check if PotentialGuaranteedUser can use the reference count associated + /// with the value we are tracking. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialGuaranteedUser(SILInstruction *User, + SILInstruction *InsertPt, + AliasAnalysis *AA); + /// We have a matching ref count inst. Return true if we advance the sequence /// and false otherwise. bool handleRefCountInstMatch(SILInstruction *RefCountInst); @@ -322,23 +328,11 @@ class TopDownRefCountState : public RefCountState { /// Uninitialize the current state. void clear(); - /// Check if PotentialDecrement can decrement the reference count associated - /// with the value we are tracking. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialDecrement(SILInstruction *PotentialDecrement, - SILInstruction *InsertPt, AliasAnalysis *AA); - - /// Check if PotentialUser could be a use of the reference counted value that - /// requires user to be alive. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialUser(SILInstruction *PotentialUser, AliasAnalysis *AA); - - /// Check if PotentialGuaranteedUser can use the reference count associated - /// with the value we are tracking. If so advance the state's sequence - /// appropriately and return true. Otherwise return false. - bool handlePotentialGuaranteedUser(SILInstruction *PotentialGuaranteedUser, - SILInstruction *InsertPt, - AliasAnalysis *AA); + /// Update this reference count's state given the instruction \p I. \p + /// InsertPt is the point furthest up the CFG where we can move the currently + /// tracked reference count. + void updateForSameLoopInst(SILInstruction *I, SILInstruction *InsertPt, + AliasAnalysis *AA); /// Returns true if the passed in ref count inst matches the ref count inst /// we are tracking. This handles generically retains/release. @@ -361,6 +355,12 @@ class TopDownRefCountState : public RefCountState { bool handleDecrement(SILInstruction *PotentialDecrement, SILInstruction *InsertPt); + /// Check if PotentialDecrement can decrement the reference count associated + /// with the value we are tracking. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialDecrement(SILInstruction *PotentialDecrement, + SILInstruction *InsertPt, AliasAnalysis *AA); + /// Returns true if given the current lattice state, do we care if the value /// we are tracking is used. bool valueCanBeUsedGivenLatticeState() const; @@ -370,6 +370,11 @@ class TopDownRefCountState : public RefCountState { bool handleUser(SILInstruction *PotentialUser, SILValue RCIdentity, AliasAnalysis *AA); + /// Check if PotentialUser could be a use of the reference counted value that + /// requires user to be alive. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialUser(SILInstruction *PotentialUser, AliasAnalysis *AA); + /// Returns true if given the current lattice state, do we care if the value /// we are tracking is used. bool valueCanBeGuaranteedUsedGivenLatticeState() const; @@ -380,6 +385,13 @@ class TopDownRefCountState : public RefCountState { SILInstruction *InsertPt, SILValue RCIdentity, AliasAnalysis *AA); + /// Check if PotentialGuaranteedUser can use the reference count associated + /// with the value we are tracking. If so advance the state's sequence + /// appropriately and return true. Otherwise return false. + bool handlePotentialGuaranteedUser(SILInstruction *PotentialGuaranteedUser, + SILInstruction *InsertPt, + AliasAnalysis *AA); + /// We have a matching ref count inst. Return true if we advance the sequence /// and false otherwise. bool handleRefCountInstMatch(SILInstruction *RefCountInst);