[llvm] r229936 - [objc-arc] Add the predicate CanDecrementRefCount.

Michael Gottesman mgottesman at apple.com
Thu Feb 19 16:02:45 PST 2015


Author: mgottesman
Date: Thu Feb 19 18:02:45 2015
New Revision: 229936

URL: http://llvm.org/viewvc/llvm-project?rev=229936&view=rev
Log:
[objc-arc] Add the predicate CanDecrementRefCount.

This is different from CanAlterRefCount since CanDecrementRefCount is
attempting to prove specifically whether or not an instruction can
decrement instead of the more general question of whether it can
decrement or increment.

Modified:
    llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
    llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
    llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.cpp
    llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.h

Modified: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp?rev=229936&r1=229935&r2=229936&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp Thu Feb 19 18:02:45 2015
@@ -605,3 +605,41 @@ bool llvm::objcarc::CanInterruptRV(ARCIn
   }
   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?");
+}

Modified: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h?rev=229936&r1=229935&r2=229936&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h Thu Feb 19 18:02:45 2015
@@ -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 GetBasicARCIns
   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
 

Modified: llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.cpp?rev=229936&r1=229935&r2=229936&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.cpp Thu Feb 19 18:02:45 2015
@@ -66,6 +66,18 @@ bool llvm::objcarc::CanAlterRefCount(con
   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,

Modified: llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.h?rev=229936&r1=229935&r2=229936&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/DependencyAnalysis.h Thu Feb 19 18:02:45 2015
@@ -71,6 +71,11 @@ bool CanUse(const Instruction *Inst, con
 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
 





More information about the llvm-commits mailing list