1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[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
This commit is contained in:
Michael Gottesman 2015-03-06 00:34:39 +00:00
parent e8f633ef7e
commit 44a01af1ff
3 changed files with 64 additions and 47 deletions

View 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;

View 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;
}

View 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