ARCRuntimeEntryPoints.h revision 023d2bbbbedc6ed991b11381a987673133be2c81
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- C++ -*---------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// \file 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// This file contains a class ARCRuntimeEntryPoints for use in 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// creating/managing references to entry points to the arc objective c runtime. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// WARNING: This file knows about certain library functions. It recognizes them 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// by name, and hardwires knowledge of their semantics. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// WARNING: This file knows about how certain Objective-C library functions are 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// used. Naive LLVM IR transformations which would otherwise be 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// behavior-preserving may break these assumptions. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ObjCARC.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace objcarc { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Declarations for ObjC runtime functions and constants. These are initialized 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// lazily to avoid cluttering up the Module with unused declarations. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ARCRuntimeEntryPoints { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum EntryPointType { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_AutoreleaseRV, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_Release, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_Retain, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_RetainBlock, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_Autorelease, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EPT_StoreStrong, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EPT_RetainRV, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EPT_RetainAutorelease, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EPT_RetainAutoreleaseRV 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ARCRuntimeEntryPoints() : TheModule(0), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoreleaseRV(0), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(0), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Retain(0), 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RetainBlock(0), 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Autorelease(0), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StoreStrong(0), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainRV(0), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainAutorelease(0), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainAutoreleaseRV(0) { } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~ARCRuntimeEntryPoints() { } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize(Module *M) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TheModule = M; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoreleaseRV = 0; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release = 0; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Retain = 0; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainBlock = 0; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Autorelease = 0; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StoreStrong = 0; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainRV = 0; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainAutorelease = 0; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RetainAutoreleaseRV = 0; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Constant *get(const EntryPointType entry) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(TheModule != 0 && "Not initialized."); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (entry) { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case EPT_AutoreleaseRV: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return getI8XRetI8XEntryPoint(AutoreleaseRV, 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "objc_autoreleaseReturnValue", true); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EPT_Release: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return getVoidRetI8XEntryPoint(Release, "objc_release"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EPT_Retain: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return getI8XRetI8XEntryPoint(Retain, "objc_retain", true); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EPT_RetainBlock: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case EPT_Autorelease: 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case EPT_StoreStrong: 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong"); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case EPT_RetainRV: 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getI8XRetI8XEntryPoint(RetainRV, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "objc_retainAutoreleasedReturnValue", true); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case EPT_RetainAutorelease: 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true); 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case EPT_RetainAutoreleaseRV: 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "objc_retainAutoreleaseReturnValue", true); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) llvm_unreachable("Switch should be a covered switch."); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private: 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Cached reference to the module which we will insert declarations into. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Module *TheModule; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *AutoreleaseRV; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for ObjC runtime function objc_release. 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *Release; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for ObjC runtime function objc_retain. 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *Retain; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Declaration for ObjC runtime function objc_retainBlock. 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Constant *RetainBlock; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Declaration for ObjC runtime function objc_autorelease. 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *Autorelease; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for objc_storeStrong(). 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *StoreStrong; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for objc_retainAutoreleasedReturnValue(). 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *RetainRV; 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for objc_retainAutorelease(). 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *RetainAutorelease; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// Declaration for objc_retainAutoreleaseReturnValue(). 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *RetainAutoreleaseRV; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Constant *getVoidRetI8XEntryPoint(Constant *&Decl, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *Name) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Decl) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Decl; 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LLVMContext &C = TheModule->getContext(); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AttributeSet Attr = 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Attribute::NoUnwind); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /*isVarArg=*/false); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *getI8XRetI8XEntryPoint(Constant *& Decl, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char *Name, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool NoUnwind = false) { 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Decl) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Decl; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LLVMContext &C = TheModule->getContext(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type *Params[] = { I8X }; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AttributeSet Attr = AttributeSet(); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NoUnwind) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Attribute::NoUnwind); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char *Name) { 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Decl) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Decl; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LLVMContext &C = TheModule->getContext(); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type *I8XX = PointerType::getUnqual(I8X); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type *Params[] = { I8XX, I8X }; 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AttributeSet Attr = 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Attribute::NoUnwind); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Attr = Attr.addAttribute(C, 1, Attribute::NoCapture); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /*isVarArg=*/false); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; // class ARCRuntimeEntryPoints 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace objcarc 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace llvm 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)