ARCRuntimeEntryPoints.h revision 462e998f076b625507d134c8c341f8cf960d1eb0
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() : TheModule(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 TheModule = M; 61 } 62 63 Constant *get(const EntryPointType entry) { 64 assert(TheModule != 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_RetainRV: 81 return getI8XRetI8XEntryPoint(RetainRV, 82 "objc_retainAutoreleasedReturnValue", true); 83 case EPT_RetainAutorelease: 84 return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", 85 true); 86 case EPT_RetainAutoreleaseRV: 87 return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, 88 "objc_retainAutoreleaseReturnValue", true); 89 } 90 91 llvm_unreachable("Switch should be a covered switch."); 92 } 93 94private: 95 /// Cached reference to the module which we will insert declarations into. 96 Module *TheModule; 97 98 /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 99 Constant *AutoreleaseRV; 100 /// Declaration for ObjC runtime function objc_release. 101 Constant *Release; 102 /// Declaration for ObjC runtime function objc_retain. 103 Constant *Retain; 104 /// Declaration for ObjC runtime function objc_retainBlock. 105 Constant *RetainBlock; 106 /// Declaration for ObjC runtime function objc_autorelease. 107 Constant *Autorelease; 108 /// Declaration for objc_storeStrong(). 109 Constant *StoreStrong; 110 /// Declaration for objc_retainAutoreleasedReturnValue(). 111 Constant *RetainRV; 112 /// Declaration for objc_retainAutorelease(). 113 Constant *RetainAutorelease; 114 /// Declaration for objc_retainAutoreleaseReturnValue(). 115 Constant *RetainAutoreleaseRV; 116 117 Constant *getVoidRetI8XEntryPoint(Constant *&Decl, 118 const char *Name) { 119 if (Decl) 120 return Decl; 121 122 LLVMContext &C = TheModule->getContext(); 123 Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; 124 AttributeSet Attr = 125 AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 126 Attribute::NoUnwind); 127 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 128 /*isVarArg=*/false); 129 return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 130 } 131 132 Constant *getI8XRetI8XEntryPoint(Constant *& Decl, 133 const char *Name, 134 bool NoUnwind = false) { 135 if (Decl) 136 return Decl; 137 138 LLVMContext &C = TheModule->getContext(); 139 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 140 Type *Params[] = { I8X }; 141 FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); 142 AttributeSet Attr = AttributeSet(); 143 144 if (NoUnwind) 145 Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex, 146 Attribute::NoUnwind); 147 148 return Decl = TheModule->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 = TheModule->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(C, AttributeSet::FunctionIndex, 163 Attribute::NoUnwind); 164 Attr = Attr.addAttribute(C, 1, Attribute::NoCapture); 165 166 FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 167 /*isVarArg=*/false); 168 169 return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 170 } 171 172}; // class ARCRuntimeEntryPoints 173 174} // namespace objcarc 175} // namespace llvm 176 177#endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 178