1023d2bbbbedc6ed991b11381a987673133be2c81Michael Gottesman//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- C++ -*---------===// 27ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// 37ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// The LLVM Compiler Infrastructure 47ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// 57ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// This file is distributed under the University of Illinois Open Source 67ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// License. See LICENSE.TXT for details. 77ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman// 87ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman//===----------------------------------------------------------------------===// 97ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// \file 107ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// This file contains a class ARCRuntimeEntryPoints for use in 117ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// creating/managing references to entry points to the arc objective c runtime. 127ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// 137ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them 147ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// by name, and hardwires knowledge of their semantics. 157ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// 167ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are 177ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// used. Naive LLVM IR transformations which would otherwise be 187ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// behavior-preserving may break these assumptions. 197ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// 207ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman//===----------------------------------------------------------------------===// 217ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 227ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman#ifndef LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 237ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman#define LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 247ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 257ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman#include "ObjCARC.h" 267ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 277ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesmannamespace llvm { 287ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesmannamespace objcarc { 297ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 307ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// Declarations for ObjC runtime functions and constants. These are initialized 317ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman/// lazily to avoid cluttering up the Module with unused declarations. 327ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesmanclass ARCRuntimeEntryPoints { 337ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesmanpublic: 347ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman enum EntryPointType { 357ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_AutoreleaseRV, 367ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_Release, 377ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_Retain, 387ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_RetainBlock, 397ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_Autorelease, 407ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_StoreStrong, 417ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_RetainRV, 427ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_RetainAutorelease, 437ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman EPT_RetainAutoreleaseRV 447ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman }; 457ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ARCRuntimeEntryPoints() : TheModule(nullptr), 47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AutoreleaseRV(nullptr), 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Release(nullptr), 49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Retain(nullptr), 50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainBlock(nullptr), 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Autorelease(nullptr), 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StoreStrong(nullptr), 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainRV(nullptr), 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainAutorelease(nullptr), 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainAutoreleaseRV(nullptr) { } 567ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 577ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman ~ARCRuntimeEntryPoints() { } 587ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 597ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman void Initialize(Module *M) { 60c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman TheModule = M; 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AutoreleaseRV = nullptr; 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Release = nullptr; 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Retain = nullptr; 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainBlock = nullptr; 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Autorelease = nullptr; 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StoreStrong = nullptr; 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainRV = nullptr; 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainAutorelease = nullptr; 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RetainAutoreleaseRV = nullptr; 707ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 717ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 727ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *get(const EntryPointType entry) { 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(TheModule != nullptr && "Not initialized."); 747ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 757ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman switch (entry) { 767ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_AutoreleaseRV: 777ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(AutoreleaseRV, 787ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman "objc_autoreleaseReturnValue", true); 797ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_Release: 807ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getVoidRetI8XEntryPoint(Release, "objc_release"); 817ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_Retain: 827ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(Retain, "objc_retain", true); 837ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_RetainBlock: 847ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false); 857ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_Autorelease: 867ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true); 877ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_StoreStrong: 887ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong"); 89462e998f076b625507d134c8c341f8cf960d1eb0Michael Gottesman case EPT_RetainRV: 90462e998f076b625507d134c8c341f8cf960d1eb0Michael Gottesman return getI8XRetI8XEntryPoint(RetainRV, 91462e998f076b625507d134c8c341f8cf960d1eb0Michael Gottesman "objc_retainAutoreleasedReturnValue", true); 927ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_RetainAutorelease: 937ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease", 947ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman true); 957ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman case EPT_RetainAutoreleaseRV: 967ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return getI8XRetI8XEntryPoint(RetainAutoreleaseRV, 977ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman "objc_retainAutoreleaseReturnValue", true); 987ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 99462e998f076b625507d134c8c341f8cf960d1eb0Michael Gottesman 100462e998f076b625507d134c8c341f8cf960d1eb0Michael Gottesman llvm_unreachable("Switch should be a covered switch."); 1017ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 1027ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1037ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesmanprivate: 1047ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Cached reference to the module which we will insert declarations into. 105c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman Module *TheModule; 1067ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1077ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 1087ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *AutoreleaseRV; 1097ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for ObjC runtime function objc_release. 1107ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *Release; 1117ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for ObjC runtime function objc_retain. 1127ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *Retain; 1137ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for ObjC runtime function objc_retainBlock. 1147ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *RetainBlock; 1157ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for ObjC runtime function objc_autorelease. 1167ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *Autorelease; 1177ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for objc_storeStrong(). 1187ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *StoreStrong; 1197ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for objc_retainAutoreleasedReturnValue(). 1207ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *RetainRV; 1217ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for objc_retainAutorelease(). 1227ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *RetainAutorelease; 1237ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /// Declaration for objc_retainAutoreleaseReturnValue(). 1247ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *RetainAutoreleaseRV; 1257ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1267ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *getVoidRetI8XEntryPoint(Constant *&Decl, 1277ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman const char *Name) { 1287ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman if (Decl) 1297ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return Decl; 1307ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 131c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman LLVMContext &C = TheModule->getContext(); 1327ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) }; 1337ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman AttributeSet Attr = 134c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 1357ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Attribute::NoUnwind); 1367ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 1377ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /*isVarArg=*/false); 138c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 1397ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 1407ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1417ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *getI8XRetI8XEntryPoint(Constant *& Decl, 1427ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman const char *Name, 1437ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman bool NoUnwind = false) { 1447ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman if (Decl) 1457ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return Decl; 1467ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 147c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman LLVMContext &C = TheModule->getContext(); 1487ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 1497ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *Params[] = { I8X }; 1507ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false); 1517ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman AttributeSet Attr = AttributeSet(); 1527ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1537ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman if (NoUnwind) 154c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex, 1557ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Attribute::NoUnwind); 1567ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 157c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 1587ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 1597ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1607ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, 1617ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman const char *Name) { 1627ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman if (Decl) 1637ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman return Decl; 1647ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 165c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman LLVMContext &C = TheModule->getContext(); 1667ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 1677ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *I8XX = PointerType::getUnqual(I8X); 1687ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Type *Params[] = { I8XX, I8X }; 1697ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1707ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman AttributeSet Attr = 171c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman AttributeSet().addAttribute(C, AttributeSet::FunctionIndex, 1727ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman Attribute::NoUnwind); 173c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman Attr = Attr.addAttribute(C, 1, Attribute::NoCapture); 1747ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1757ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params, 1767ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman /*isVarArg=*/false); 1777ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 178c3e6edba384e023da4e974faca4e28b2276d575fMichael Gottesman return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr); 1797ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman } 1807ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1817ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman}; // class ARCRuntimeEntryPoints 1827ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1837ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman} // namespace objcarc 1847ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman} // namespace llvm 1857ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman 1867ec67156b060ee4e0aac35eed24088ebcbe40aeeMichael Gottesman#endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H 187