diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/ARCInstKind.cpp | 38 | ||||
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/ARCInstKind.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h | 5 |
4 files changed, 61 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ARCInstKind.cpp b/llvm/lib/Transforms/ObjCARC/ARCInstKind.cpp index e086e1f5239..f1e9dcecfc8 100644 --- a/llvm/lib/Transforms/ObjCARC/ARCInstKind.cpp +++ b/llvm/lib/Transforms/ObjCARC/ARCInstKind.cpp @@ -605,3 +605,41 @@ bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) { } llvm_unreachable("covered switch isn't covered?"); } + +bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) { + switch (Kind) { + case ARCInstKind::Retain: + case ARCInstKind::RetainRV: + case ARCInstKind::Autorelease: + case ARCInstKind::AutoreleaseRV: + case ARCInstKind::NoopCast: + case ARCInstKind::FusedRetainAutorelease: + case ARCInstKind::FusedRetainAutoreleaseRV: + case ARCInstKind::IntrinsicUser: + case ARCInstKind::User: + case ARCInstKind::None: + return false; + + // The cases below are conservative. + + // RetainBlock can result in user defined copy constructors being called + // implying releases may occur. + case ARCInstKind::RetainBlock: + case ARCInstKind::Release: + case ARCInstKind::AutoreleasepoolPush: + case ARCInstKind::AutoreleasepoolPop: + case ARCInstKind::LoadWeakRetained: + case ARCInstKind::StoreWeak: + case ARCInstKind::InitWeak: + case ARCInstKind::LoadWeak: + case ARCInstKind::MoveWeak: + case ARCInstKind::CopyWeak: + case ARCInstKind::DestroyWeak: + case ARCInstKind::StoreStrong: + case ARCInstKind::CallOrUser: + case ARCInstKind::Call: + return true; + } + + llvm_unreachable("covered switch isn't covered?"); +} diff --git a/llvm/lib/Transforms/ObjCARC/ARCInstKind.h b/llvm/lib/Transforms/ObjCARC/ARCInstKind.h index e8e4fed5489..636c65c9b62 100644 --- a/llvm/lib/Transforms/ObjCARC/ARCInstKind.h +++ b/llvm/lib/Transforms/ObjCARC/ARCInstKind.h @@ -51,7 +51,7 @@ enum class ARCInstKind { CallOrUser, ///< could call objc_release and/or "use" pointers Call, ///< could call objc_release User, ///< could "use" a pointer - None ///< anything else + None ///< anything that is inert from an ARC perspective. }; raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class); @@ -110,9 +110,13 @@ static inline ARCInstKind GetBasicARCInstKind(const Value *V) { return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User; } -/// \brief Determine what kind of construct V is. +/// Map V to its ARCInstKind equivalence class. ARCInstKind GetARCInstKind(const Value *V); +/// Returns false if conservatively we can prove that any instruction mapped to +/// this kind can not decrement ref counts. Returns true otherwise. +bool CanDecrementRefCount(ARCInstKind Kind); + } // end namespace objcarc } // end namespace llvm diff --git a/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp b/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp index 9eb91a55a01..4985d0ebfd0 100644 --- a/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp +++ b/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp @@ -66,6 +66,18 @@ bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr, return true; } +bool llvm::objcarc::CanDecrementRefCount(const Instruction *Inst, + const Value *Ptr, + ProvenanceAnalysis &PA, + ARCInstKind Class) { + // First perform a quick check if Class can not touch ref counts. + if (!CanDecrementRefCount(Class)) + return false; + + // Otherwise, just use CanAlterRefCount for now. + return CanAlterRefCount(Inst, Ptr, PA, Class); +} + /// Test whether the given instruction can "use" the given pointer's object in a /// way that requires the reference count to be positive. bool llvm::objcarc::CanUse(const Instruction *Inst, const Value *Ptr, diff --git a/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h b/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h index 77e4bdf5021..e5f9db9ada1 100644 --- a/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h +++ b/llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h @@ -71,6 +71,11 @@ bool CanUse(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, bool CanAlterRefCount(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class); +/// Returns true if we can not conservatively prove that Inst can not decrement +/// the reference count of Ptr. Returns false if we can. +bool CanDecrementRefCount(const Instruction *Inst, const Value *Ptr, + ProvenanceAnalysis &PA, ARCInstKind Class); + } // namespace objcarc } // namespace llvm |

