ARCRuntimeEntryPoints.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- 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. /// \file
  10. /// This file contains a class ARCRuntimeEntryPoints for use in
  11. /// creating/managing references to entry points to the arc objective c runtime.
  12. ///
  13. /// WARNING: This file knows about certain library functions. It recognizes them
  14. /// by name, and hardwires knowledge of their semantics.
  15. ///
  16. /// WARNING: This file knows about how certain Objective-C library functions are
  17. /// used. Naive LLVM IR transformations which would otherwise be
  18. /// behavior-preserving may break these assumptions.
  19. ///
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
  22. #define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
  23. #include "ObjCARC.h"
  24. namespace llvm {
  25. namespace objcarc {
  26. enum class ARCRuntimeEntryPointKind {
  27. AutoreleaseRV,
  28. Release,
  29. Retain,
  30. RetainBlock,
  31. Autorelease,
  32. StoreStrong,
  33. RetainRV,
  34. RetainAutorelease,
  35. RetainAutoreleaseRV,
  36. };
  37. /// Declarations for ObjC runtime functions and constants. These are initialized
  38. /// lazily to avoid cluttering up the Module with unused declarations.
  39. class ARCRuntimeEntryPoints {
  40. public:
  41. ARCRuntimeEntryPoints() : TheModule(nullptr),
  42. AutoreleaseRV(nullptr),
  43. Release(nullptr),
  44. Retain(nullptr),
  45. RetainBlock(nullptr),
  46. Autorelease(nullptr),
  47. StoreStrong(nullptr),
  48. RetainRV(nullptr),
  49. RetainAutorelease(nullptr),
  50. RetainAutoreleaseRV(nullptr) { }
  51. void init(Module *M) {
  52. TheModule = M;
  53. AutoreleaseRV = nullptr;
  54. Release = nullptr;
  55. Retain = nullptr;
  56. RetainBlock = nullptr;
  57. Autorelease = nullptr;
  58. StoreStrong = nullptr;
  59. RetainRV = nullptr;
  60. RetainAutorelease = nullptr;
  61. RetainAutoreleaseRV = nullptr;
  62. }
  63. Constant *get(ARCRuntimeEntryPointKind kind) {
  64. assert(TheModule != nullptr && "Not initialized.");
  65. switch (kind) {
  66. case ARCRuntimeEntryPointKind::AutoreleaseRV:
  67. return getI8XRetI8XEntryPoint(AutoreleaseRV,
  68. "objc_autoreleaseReturnValue", true);
  69. case ARCRuntimeEntryPointKind::Release:
  70. return getVoidRetI8XEntryPoint(Release, "objc_release");
  71. case ARCRuntimeEntryPointKind::Retain:
  72. return getI8XRetI8XEntryPoint(Retain, "objc_retain", true);
  73. case ARCRuntimeEntryPointKind::RetainBlock:
  74. return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false);
  75. case ARCRuntimeEntryPointKind::Autorelease:
  76. return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true);
  77. case ARCRuntimeEntryPointKind::StoreStrong:
  78. return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong");
  79. case ARCRuntimeEntryPointKind::RetainRV:
  80. return getI8XRetI8XEntryPoint(RetainRV,
  81. "objc_retainAutoreleasedReturnValue", true);
  82. case ARCRuntimeEntryPointKind::RetainAutorelease:
  83. return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease",
  84. true);
  85. case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:
  86. return getI8XRetI8XEntryPoint(RetainAutoreleaseRV,
  87. "objc_retainAutoreleaseReturnValue", true);
  88. }
  89. llvm_unreachable("Switch should be a covered switch.");
  90. }
  91. private:
  92. /// Cached reference to the module which we will insert declarations into.
  93. Module *TheModule;
  94. /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
  95. Constant *AutoreleaseRV;
  96. /// Declaration for ObjC runtime function objc_release.
  97. Constant *Release;
  98. /// Declaration for ObjC runtime function objc_retain.
  99. Constant *Retain;
  100. /// Declaration for ObjC runtime function objc_retainBlock.
  101. Constant *RetainBlock;
  102. /// Declaration for ObjC runtime function objc_autorelease.
  103. Constant *Autorelease;
  104. /// Declaration for objc_storeStrong().
  105. Constant *StoreStrong;
  106. /// Declaration for objc_retainAutoreleasedReturnValue().
  107. Constant *RetainRV;
  108. /// Declaration for objc_retainAutorelease().
  109. Constant *RetainAutorelease;
  110. /// Declaration for objc_retainAutoreleaseReturnValue().
  111. Constant *RetainAutoreleaseRV;
  112. Constant *getVoidRetI8XEntryPoint(Constant *&Decl,
  113. const char *Name) {
  114. if (Decl)
  115. return Decl;
  116. LLVMContext &C = TheModule->getContext();
  117. Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
  118. AttributeSet Attr =
  119. AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
  120. Attribute::NoUnwind);
  121. FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
  122. /*isVarArg=*/false);
  123. return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  124. }
  125. Constant *getI8XRetI8XEntryPoint(Constant *& Decl,
  126. const char *Name,
  127. bool NoUnwind = false) {
  128. if (Decl)
  129. return Decl;
  130. LLVMContext &C = TheModule->getContext();
  131. Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
  132. Type *Params[] = { I8X };
  133. FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false);
  134. AttributeSet Attr = AttributeSet();
  135. if (NoUnwind)
  136. Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex,
  137. Attribute::NoUnwind);
  138. return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  139. }
  140. Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl,
  141. const char *Name) {
  142. if (Decl)
  143. return Decl;
  144. LLVMContext &C = TheModule->getContext();
  145. Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
  146. Type *I8XX = PointerType::getUnqual(I8X);
  147. Type *Params[] = { I8XX, I8X };
  148. AttributeSet Attr =
  149. AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
  150. Attribute::NoUnwind);
  151. Attr = Attr.addAttribute(C, 1, Attribute::NoCapture);
  152. FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
  153. /*isVarArg=*/false);
  154. return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  155. }
  156. }; // class ARCRuntimeEntryPoints
  157. } // namespace objcarc
  158. } // namespace llvm
  159. #endif