ARCInstKind.h 4.7 KB

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