LLVM API Documentation
00001 //===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- C++ -*---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// \file 00010 /// This file contains a class ARCRuntimeEntryPoints for use in 00011 /// creating/managing references to entry points to the arc objective c runtime. 00012 /// 00013 /// WARNING: This file knows about certain library functions. It recognizes them 00014 /// by name, and hardwires knowledge of their semantics. 00015 /// 00016 /// WARNING: This file knows about how certain Objective-C library functions are 00017 /// used. Naive LLVM IR transformations which would otherwise be 00018 /// behavior-preserving may break these assumptions. 00019 /// 00020 //===----------------------------------------------------------------------===// 00021 00022 #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 00023 #define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 00024 00025 #include "ObjCARC.h" 00026 00027 namespace llvm { 00028 namespace objcarc { 00029 00030 /// Declarations for ObjC runtime functions and constants. These are initialized 00031 /// lazily to avoid cluttering up the Module with unused declarations. 00032 class ARCRuntimeEntryPoints { 00033 public: 00034 enum EntryPointType { 00035 EPT_AutoreleaseRV, 00036 EPT_Release, 00037 EPT_Retain, 00038 EPT_RetainBlock, 00039 EPT_Autorelease, 00040 EPT_StoreStrong, 00041 EPT_RetainRV, 00042 EPT_RetainAutorelease, 00043 EPT_RetainAutoreleaseRV 00044 }; 00045 00046 ARCRuntimeEntryPoints() : TheModule(nullptr), 00047 AutoreleaseRV(nullptr), 00048 Release(nullptr), 00049 Retain(nullptr), 00050 RetainBlock(nullptr), 00051 Autorelease(nullptr), 00052 StoreStrong(nullptr), 00053 RetainRV(nullptr), 00054 RetainAutorelease(nullptr), 00055 RetainAutoreleaseRV(nullptr) { } 00056 00057 ~ARCRuntimeEntryPoints() { } 00058 00059 void Initialize(Module *M) { 00060 TheModule = M; 00061 AutoreleaseRV = nullptr; 00062 Release = nullptr; 00063 Retain = nullptr; 00064 RetainBlock = nullptr; 00065 Autorelease = nullptr; 00066 StoreStrong = nullptr; 00067 RetainRV = nullptr; 00068 RetainAutorelease = nullptr; 00069 RetainAutoreleaseRV = nullptr; 00070 } 00071 00072 Constant *get(const EntryPointType entry) { 00073 assert(TheModule != nullptr && "Not initialized."); 00074 00075 switch (entry) { 00076 case EPT_AutoreleaseRV: 00077 return getI8XRetI8XEntryPoint(AutoreleaseRV, 00078 "objc_autoreleaseReturnValue", true); 00079 case EPT_Release: 00080 return getVoidRetI8XEntryPoint(Release, "objc_release"); 00081 case EPT_Retain: 00082 return getI8XRetI8XEntryPoint(Retain, "objc_retain", true); 00083 case EPT_RetainBlock: 00084 return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false); 00085 case EPT_Autorelease: 00086 return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true); 00087 case EPT_StoreStrong: 00088 return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong"); 00089 case EPT_RetainRV: 00090 return getI8XRetI8XEntryPoint(RetainRV, 00091 "objc_retainAutoreleasedReturnValue", true); 00092 case EPT_RetainAutorelease: 00093 return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", 00094 true); 00095 case EPT_RetainAutoreleaseRV: 00096 return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, 00097 "objc_retainAutoreleaseReturnValue", true); 00098 } 00099 00100 llvm_unreachable("Switch should be a covered switch."); 00101 } 00102 00103 private: 00104 /// Cached reference to the module which we will insert declarations into. 00105 Module *TheModule; 00106 00107 /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 00108 Constant *AutoreleaseRV; 00109 /// Declaration for ObjC runtime function objc_release. 00110 Constant *Release; 00111 /// Declaration for ObjC runtime function objc_retain. 00112 Constant *Retain; 00113 /// Declaration for ObjC runtime function objc_retainBlock. 00114 Constant *RetainBlock; 00115 /// Declaration for ObjC runtime function objc_autorelease. 00116 Constant *Autorelease; 00117 /// Declaration for objc_storeStrong(). 00118 Constant *StoreStrong; 00119 /// Declaration for objc_retainAutoreleasedReturnValue(). 00120 Constant *RetainRV; 00121 /// Declaration for objc_retainAutorelease(). 00122 Constant *RetainAutorelease; 00123 /// Declaration for objc_retainAutoreleaseReturnValue(). 00124 Constant *RetainAutoreleaseRV; 00125 00126 Constant *getVoidRetI8XEntryPoint(Constant *&Decl, 00127 const char *Name) { 00128 if (Decl) 00129 return Decl; 00130 00131 LLVMContext &C = TheModule->getContext(); 00132 Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; 00133 AttributeSet Attr = 00134 AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 00135 Attribute::NoUnwind); 00136 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 00137 /*isVarArg=*/false); 00138 return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 00139 } 00140 00141 Constant *getI8XRetI8XEntryPoint(Constant *& Decl, 00142 const char *Name, 00143 bool NoUnwind = false) { 00144 if (Decl) 00145 return Decl; 00146 00147 LLVMContext &C = TheModule->getContext(); 00148 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 00149 Type *Params[] = { I8X }; 00150 FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); 00151 AttributeSet Attr = AttributeSet(); 00152 00153 if (NoUnwind) 00154 Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex, 00155 Attribute::NoUnwind); 00156 00157 return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 00158 } 00159 00160 Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, 00161 const char *Name) { 00162 if (Decl) 00163 return Decl; 00164 00165 LLVMContext &C = TheModule->getContext(); 00166 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 00167 Type *I8XX = PointerType::getUnqual(I8X); 00168 Type *Params[] = { I8XX, I8X }; 00169 00170 AttributeSet Attr = 00171 AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 00172 Attribute::NoUnwind); 00173 Attr = Attr.addAttribute(C, 1, Attribute::NoCapture); 00174 00175 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 00176 /*isVarArg=*/false); 00177 00178 return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 00179 } 00180 00181 }; // class ARCRuntimeEntryPoints 00182 00183 } // namespace objcarc 00184 } // namespace llvm 00185 00186 #endif