Home | History | Annotate | Download | only in Analysis
      1 //===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
     11 #define LLVM_ANALYSIS_OBJCARCINSTKIND_H
     12 
     13 #include "llvm/IR/Function.h"
     14 #include "llvm/IR/Instructions.h"
     15 
     16 namespace llvm {
     17 namespace objcarc {
     18 
     19 /// \enum ARCInstKind
     20 ///
     21 /// \brief Equivalence classes of instructions in the ARC Model.
     22 ///
     23 /// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
     24 /// we instead operate on equivalence classes of instructions.
     25 ///
     26 /// TODO: This should be split into two enums: a runtime entry point enum
     27 /// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
     28 /// with effects of instructions in the ARC model (which would handle the notion
     29 /// of a User or CallOrUser).
     30 enum class ARCInstKind {
     31   Retain,                   ///< objc_retain
     32   RetainRV,                 ///< objc_retainAutoreleasedReturnValue
     33   ClaimRV,                  ///< objc_unsafeClaimAutoreleasedReturnValue
     34   RetainBlock,              ///< objc_retainBlock
     35   Release,                  ///< objc_release
     36   Autorelease,              ///< objc_autorelease
     37   AutoreleaseRV,            ///< objc_autoreleaseReturnValue
     38   AutoreleasepoolPush,      ///< objc_autoreleasePoolPush
     39   AutoreleasepoolPop,       ///< objc_autoreleasePoolPop
     40   NoopCast,                 ///< objc_retainedObject, etc.
     41   FusedRetainAutorelease,   ///< objc_retainAutorelease
     42   FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
     43   LoadWeakRetained,         ///< objc_loadWeakRetained (primitive)
     44   StoreWeak,                ///< objc_storeWeak (primitive)
     45   InitWeak,                 ///< objc_initWeak (derived)
     46   LoadWeak,                 ///< objc_loadWeak (derived)
     47   MoveWeak,                 ///< objc_moveWeak (derived)
     48   CopyWeak,                 ///< objc_copyWeak (derived)
     49   DestroyWeak,              ///< objc_destroyWeak (derived)
     50   StoreStrong,              ///< objc_storeStrong (derived)
     51   IntrinsicUser,            ///< clang.arc.use
     52   CallOrUser,               ///< could call objc_release and/or "use" pointers
     53   Call,                     ///< could call objc_release
     54   User,                     ///< could "use" a pointer
     55   None                      ///< anything that is inert from an ARC perspective.
     56 };
     57 
     58 raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
     59 
     60 /// \brief Test if the given class is a kind of user.
     61 bool IsUser(ARCInstKind Class);
     62 
     63 /// \brief Test if the given class is objc_retain or equivalent.
     64 bool IsRetain(ARCInstKind Class);
     65 
     66 /// \brief Test if the given class is objc_autorelease or equivalent.
     67 bool IsAutorelease(ARCInstKind Class);
     68 
     69 /// \brief Test if the given class represents instructions which return their
     70 /// argument verbatim.
     71 bool IsForwarding(ARCInstKind Class);
     72 
     73 /// \brief Test if the given class represents instructions which do nothing if
     74 /// passed a null pointer.
     75 bool IsNoopOnNull(ARCInstKind Class);
     76 
     77 /// \brief Test if the given class represents instructions which are always safe
     78 /// to mark with the "tail" keyword.
     79 bool IsAlwaysTail(ARCInstKind Class);
     80 
     81 /// \brief Test if the given class represents instructions which are never safe
     82 /// to mark with the "tail" keyword.
     83 bool IsNeverTail(ARCInstKind Class);
     84 
     85 /// \brief Test if the given class represents instructions which are always safe
     86 /// to mark with the nounwind attribute.
     87 bool IsNoThrow(ARCInstKind Class);
     88 
     89 /// Test whether the given instruction can autorelease any pointer or cause an
     90 /// autoreleasepool pop.
     91 bool CanInterruptRV(ARCInstKind Class);
     92 
     93 /// \brief Determine if F is one of the special known Functions.  If it isn't,
     94 /// return ARCInstKind::CallOrUser.
     95 ARCInstKind GetFunctionClass(const Function *F);
     96 
     97 /// \brief Determine which objc runtime call instruction class V belongs to.
     98 ///
     99 /// This is similar to GetARCInstKind except that it only detects objc
    100 /// runtime calls. This allows it to be faster.
    101 ///
    102 inline ARCInstKind GetBasicARCInstKind(const Value *V) {
    103   if (const CallInst *CI = dyn_cast<CallInst>(V)) {
    104     if (const Function *F = CI->getCalledFunction())
    105       return GetFunctionClass(F);
    106     // Otherwise, be conservative.
    107     return ARCInstKind::CallOrUser;
    108   }
    109 
    110   // Otherwise, be conservative.
    111   return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
    112 }
    113 
    114 /// Map V to its ARCInstKind equivalence class.
    115 ARCInstKind GetARCInstKind(const Value *V);
    116 
    117 /// Returns false if conservatively we can prove that any instruction mapped to
    118 /// this kind can not decrement ref counts. Returns true otherwise.
    119 bool CanDecrementRefCount(ARCInstKind Kind);
    120 
    121 } // end namespace objcarc
    122 } // end namespace llvm
    123 
    124 #endif
    125