ARCRuntimeEntryPoints.h revision 7ec67156b060ee4e0aac35eed24088ebcbe40aee
1//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- mode: 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 22#ifndef LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 23#define LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 24 25#include "ObjCARC.h" 26 27namespace llvm { 28namespace objcarc { 29 30/// Declarations for ObjC runtime functions and constants. These are initialized 31/// lazily to avoid cluttering up the Module with unused declarations. 32class ARCRuntimeEntryPoints { 33public: 34 enum EntryPointType { 35 EPT_AutoreleaseRV, 36 EPT_Release, 37 EPT_Retain, 38 EPT_RetainBlock, 39 EPT_Autorelease, 40 EPT_StoreStrong, 41 EPT_RetainRV, 42 EPT_RetainAutorelease, 43 EPT_RetainAutoreleaseRV 44 }; 45 46 ARCRuntimeEntryPoints() : Module(0), 47 AutoreleaseRV(0), 48 Release(0), 49 Retain(0), 50 RetainBlock(0), 51 Autorelease(0), 52 StoreStrong(0), 53 RetainRV(0), 54 RetainAutorelease(0), 55 RetainAutoreleaseRV(0) { } 56 57 ~ARCRuntimeEntryPoints() { } 58 59 void Initialize(Module *M) { 60 Module = M; 61 } 62 63 Constant *get(const EntryPointType entry) { 64 assert(Module != 0 && "Not initialized."); 65 66 switch (entry) { 67 case EPT_AutoreleaseRV: 68 return getI8XRetI8XEntryPoint(AutoreleaseRV, 69 "objc_autoreleaseReturnValue", true); 70 case EPT_Release: 71 return getVoidRetI8XEntryPoint(Release, "objc_release"); 72 case EPT_Retain: 73 return getI8XRetI8XEntryPoint(Retain, "objc_retain", true); 74 case EPT_RetainBlock: 75 return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false); 76 case EPT_Autorelease: 77 return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true); 78 case EPT_StoreStrong: 79 return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong"); 80 case EPT_RetainAutorelease: 81 return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", 82 true); 83 case EPT_RetainAutoreleaseRV: 84 return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, 85 "objc_retainAutoreleaseReturnValue", true); 86 case EPT_RetainRV: 87 return getI8XRetI8XEntryPoint(RetainRV, 88 "objc_retainAutoreleasedReturnValue", true); 89 } 90 } 91 92private: 93 /// Cached reference to the module which we will insert declarations into. 94 Module *Module; 95 96 /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 97 Constant *AutoreleaseRV; 98 /// Declaration for ObjC runtime function objc_release. 99 Constant *Release; 100 /// Declaration for ObjC runtime function objc_retain. 101 Constant *Retain; 102 /// Declaration for ObjC runtime function objc_retainBlock. 103 Constant *RetainBlock; 104 /// Declaration for ObjC runtime function objc_autorelease. 105 Constant *Autorelease; 106 /// Declaration for objc_storeStrong(). 107 Constant *StoreStrong; 108 /// Declaration for objc_retainAutoreleasedReturnValue(). 109 Constant *RetainRV; 110 /// Declaration for objc_retainAutorelease(). 111 Constant *RetainAutorelease; 112 /// Declaration for objc_retainAutoreleaseReturnValue(). 113 Constant *RetainAutoreleaseRV; 114 115 Constant *getVoidRetI8XEntryPoint(Constant *&Decl, 116 const char *Name) { 117 if (Decl) 118 return Decl; 119 120 LLVMContext &C = Module->getContext(); 121 Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; 122 AttributeSet Attr = 123 AttributeSet().addAttribute(Module->getContext(), 124 AttributeSet::FunctionIndex, 125 Attribute::NoUnwind); 126 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 127 /*isVarArg=*/false); 128 return Decl = Module->getOrInsertFunction(Name, Fty, Attr); 129 } 130 131 Constant *getI8XRetI8XEntryPoint(Constant *& Decl, 132 const char *Name, 133 bool NoUnwind = false) { 134 if (Decl) 135 return Decl; 136 137 LLVMContext &C = Module->getContext(); 138 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 139 Type *Params[] = { I8X }; 140 FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); 141 AttributeSet Attr = AttributeSet(); 142 143 if (NoUnwind) 144 Attr = Attr.addAttribute(Module->getContext(), 145 AttributeSet::FunctionIndex, 146 Attribute::NoUnwind); 147 148 return Decl = Module->getOrInsertFunction(Name, Fty, Attr); 149 } 150 151 Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, 152 const char *Name) { 153 if (Decl) 154 return Decl; 155 156 LLVMContext &C = Module->getContext(); 157 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 158 Type *I8XX = PointerType::getUnqual(I8X); 159 Type *Params[] = { I8XX, I8X }; 160 161 AttributeSet Attr = 162 AttributeSet().addAttribute(Module->getContext(), 163 AttributeSet::FunctionIndex, 164 Attribute::NoUnwind); 165 Attr = Attr.addAttribute(Module->getContext(), 1, Attribute::NoCapture); 166 167 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 168 /*isVarArg=*/false); 169 170 return Decl = Module->getOrInsertFunction(Name, Fty, Attr); 171 } 172 173}; // class ARCRuntimeEntryPoints 174 175} // namespace objcarc 176} // namespace llvm 177 178#endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 179