ObjCARCInstKind.h 5.0 KB

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