ARCRuntimeEntryPoints.h revision 462e998f076b625507d134c8c341f8cf960d1eb0
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization --*- mode: c++ -*---===//
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//                     The LLVM Compiler Infrastructure
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// This file is distributed under the University of Illinois Open Source
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// License. See LICENSE.TXT for details.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//===----------------------------------------------------------------------===//
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/// \file
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// This file contains a class ARCRuntimeEntryPoints for use in
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// creating/managing references to entry points to the arc objective c runtime.
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// WARNING: This file knows about certain library functions. It recognizes them
146e3e42296b0d7a93325146d9c9a7e23ef90760fecommit-bot@chromium.org/// by name, and hardwires knowledge of their semantics.
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// WARNING: This file knows about how certain Objective-C library functions are
178b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org/// used. Naive LLVM IR transformations which would otherwise be
188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org/// behavior-preserving may break these assumptions.
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//===----------------------------------------------------------------------===//
21112706d4c566e283890322bb246b4b86d59837e1vandebo@chromium.org
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H
23c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#define LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ObjCARC.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.orgnamespace llvm {
2861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.orgnamespace objcarc {
2961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org
3061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org/// Declarations for ObjC runtime functions and constants. These are initialized
3161e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org/// lazily to avoid cluttering up the Module with unused declarations.
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass ARCRuntimeEntryPoints {
334516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.compublic:
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  enum EntryPointType {
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_AutoreleaseRV,
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_Release,
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_Retain,
384516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com    EPT_RetainBlock,
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_Autorelease,
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_StoreStrong,
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_RetainRV,
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_RetainAutorelease,
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    EPT_RetainAutoreleaseRV
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  };
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  ARCRuntimeEntryPoints() : TheModule(0),
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            AutoreleaseRV(0),
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            Release(0),
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            Retain(0),
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            RetainBlock(0),
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            Autorelease(0),
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            StoreStrong(0),
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            RetainRV(0),
5483f7bc30af2837c985934e14597caec332899a1creed@android.com                            RetainAutorelease(0),
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            RetainAutoreleaseRV(0) { }
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  ~ARCRuntimeEntryPoints() { }
58f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com
595f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com  void Initialize(Module *M) {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    TheModule = M;
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
63586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com  Constant *get(const EntryPointType entry) {
64586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    assert(TheModule != 0 && "Not initialized.");
65586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com
66586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    switch (entry) {
67586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    case EPT_AutoreleaseRV:
68586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com      return getI8XRetI8XEntryPoint(AutoreleaseRV,
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    "objc_autoreleaseReturnValue", true);
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case EPT_Release:
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return getVoidRetI8XEntryPoint(Release, "objc_release");
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case EPT_Retain:
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return getI8XRetI8XEntryPoint(Retain, "objc_retain", true);
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case EPT_RetainBlock:
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false);
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case EPT_Autorelease:
77586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com      return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true);
78586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    case EPT_StoreStrong:
79672588b684d484dce6ae251e9e163e4a46924322reed@google.com      return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong");
80586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    case EPT_RetainRV:
81586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com      return getI8XRetI8XEntryPoint(RetainRV,
8261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org                                    "objc_retainAutoreleasedReturnValue", true);
83586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    case EPT_RetainAutorelease:
84586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com      return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease",
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    true);
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case EPT_RetainAutoreleaseRV:
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return getI8XRetI8XEntryPoint(RetainAutoreleaseRV,
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    "objc_retainAutoreleaseReturnValue", true);
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
914516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com    llvm_unreachable("Switch should be a covered switch.");
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9486b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.comprivate:
9586b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  /// Cached reference to the module which we will insert declarations into.
9686b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  Module *TheModule;
97e5ea500d4714a7d84de2bf913e81be3b65d2de68reed
9886b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
9986b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  Constant *AutoreleaseRV;
10080e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com  /// Declaration for ObjC runtime function objc_release.
10180e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com  Constant *Release;
102e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  /// Declaration for ObjC runtime function objc_retain.
10380e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com  Constant *Retain;
10480e1459c32f5f3acbc688ae4f0e046aa283e8c3areed@google.com  /// Declaration for ObjC runtime function objc_retainBlock.
10586b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  Constant *RetainBlock;
10686b2e43a33c486a0b150aa14fadf7af8323a11f5reed@google.com  /// Declaration for ObjC runtime function objc_autorelease.
107e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  Constant *Autorelease;
108e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  /// Declaration for objc_storeStrong().
109e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  Constant *StoreStrong;
110d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org  /// Declaration for objc_retainAutoreleasedReturnValue().
111d5414e5efe0a6a0bce0b5499e2358e2be4cb9b61commit-bot@chromium.org  Constant *RetainRV;
112e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  /// Declaration for objc_retainAutorelease().
11302d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com  Constant *RetainAutorelease;
11461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org  /// Declaration for objc_retainAutoreleaseReturnValue().
11561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org  Constant *RetainAutoreleaseRV;
11661e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org
11761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org  Constant *getVoidRetI8XEntryPoint(Constant *&Decl,
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    const char *Name) {
11961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    if (Decl)
12061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org      return Decl;
121383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com
122383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com    LLVMContext &C = TheModule->getContext();
12361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
12461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    AttributeSet Attr =
125169a0ed50a5e451711c341795572e7177a540a24mike@reedtribe.org      AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                  Attribute::NoUnwind);
12761e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
12861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org                                          /*isVarArg=*/false);
12961e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
13061e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org  }
131f0aed97aec3fa1c7f6460d8d6327358f3dcbabe6reed
13261e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org  Constant *getI8XRetI8XEntryPoint(Constant *& Decl,
13361e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org                                   const char *Name,
1341195a28892d37ae9632e81e1bc2407cf644522d2mike@reedtribe.org                                   bool NoUnwind = false) {
13561e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    if (Decl)
1361195a28892d37ae9632e81e1bc2407cf644522d2mike@reedtribe.org      return Decl;
137e5ea500d4714a7d84de2bf913e81be3b65d2de68reed
13861e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    LLVMContext &C = TheModule->getContext();
139383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
140383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com    Type *Params[] = { I8X };
141383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com    FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false);
142e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    AttributeSet Attr = AttributeSet();
143e5ea500d4714a7d84de2bf913e81be3b65d2de68reed
144383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com    if (NoUnwind)
145383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com      Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex,
146e5ea500d4714a7d84de2bf913e81be3b65d2de68reed                               Attribute::NoUnwind);
147e5ea500d4714a7d84de2bf913e81be3b65d2de68reed
1480e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
149e5ea500d4714a7d84de2bf913e81be3b65d2de68reed  }
1500e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org
1510e8d0d6cdc2e02946b099006d0a47e60764905e5commit-bot@chromium.org  Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl,
152383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com                                       const char *Name) {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (Decl)
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return Decl;
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15649f085dddff10473b6ebf832a974288300224e60bsalomon    LLVMContext &C = TheModule->getContext();
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
158ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    Type *I8XX = PointerType::getUnqual(I8X);
159f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com    Type *Params[] = { I8XX, I8X };
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16149f085dddff10473b6ebf832a974288300224e60bsalomon    AttributeSet Attr =
162672588b684d484dce6ae251e9e163e4a46924322reed@google.com      AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
163303c4758ec7062daf1531c3642e9c7887423ef1breed@google.com                                  Attribute::NoUnwind);
16461e96cd44624c9faceb625519c1b29775b161f45commit-bot@chromium.org    Attr = Attr.addAttribute(C, 1, Attribute::NoCapture);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
1675f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com                                          /*isVarArg=*/false);
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
1715f62ed74342e44cb1b9671ffdac47c6a81416136reed@google.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; // class ARCRuntimeEntryPoints
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} // namespace objcarc
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} // namespace llvm
176672588b684d484dce6ae251e9e163e4a46924322reed@google.com
177dcea5300dc028b5ea210d778b9e34a7504fee6d2reed@google.com#endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H
178672588b684d484dce6ae251e9e163e4a46924322reed@google.com