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)