6756f2f7d78107f541bf7456c4e507d6cdcc8f5e
[oota-llvm.git] / lib / Transforms / ObjCARC / ARCRuntimeEntryPoints.h
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
27 namespace llvm {
28 namespace objcarc {
29
30 /// Declarations for ObjC runtime functions and constants. These are initialized
31 /// lazily to avoid cluttering up the Module with unused declarations.
32 class ARCRuntimeEntryPoints {
33 public:
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_RetainAutorelease:
81       return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease",
82                                     true);
83     case EPT_RetainAutoreleaseRV:
84       return getI8XRetI8XEntryPoint(RetainAutoreleaseRV,
85                                     "objc_retainAutoreleaseReturnValue", true);
86     case EPT_RetainRV:
87       return getI8XRetI8XEntryPoint(RetainRV,
88                                     "objc_retainAutoreleasedReturnValue", true);
89     }
90   }
91
92 private:
93   /// Cached reference to the module which we will insert declarations into.
94   Module *TheModule;
95
96   /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
97   Constant *AutoreleaseRV;
98   /// Declaration for ObjC runtime function objc_release.
99   Constant *Release;
100   /// Declaration for ObjC runtime function objc_retain.
101   Constant *Retain;
102   /// Declaration for ObjC runtime function objc_retainBlock.
103   Constant *RetainBlock;
104   /// Declaration for ObjC runtime function objc_autorelease.
105   Constant *Autorelease;
106   /// Declaration for objc_storeStrong().
107   Constant *StoreStrong;
108   /// Declaration for objc_retainAutoreleasedReturnValue().
109   Constant *RetainRV;
110   /// Declaration for objc_retainAutorelease().
111   Constant *RetainAutorelease;
112   /// Declaration for objc_retainAutoreleaseReturnValue().
113   Constant *RetainAutoreleaseRV;
114
115   Constant *getVoidRetI8XEntryPoint(Constant *&Decl,
116                                     const char *Name) {
117     if (Decl)
118       return Decl;
119
120     LLVMContext &C = TheModule->getContext();
121     Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
122     AttributeSet Attr =
123       AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
124                                   Attribute::NoUnwind);
125     FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
126                                           /*isVarArg=*/false);
127     return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
128   }
129
130   Constant *getI8XRetI8XEntryPoint(Constant *& Decl,
131                                    const char *Name,
132                                    bool NoUnwind = false) {
133     if (Decl)
134       return Decl;
135
136     LLVMContext &C = TheModule->getContext();
137     Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
138     Type *Params[] = { I8X };
139     FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false);
140     AttributeSet Attr = AttributeSet();
141
142     if (NoUnwind)
143       Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex,
144                                Attribute::NoUnwind);
145
146     return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
147   }
148
149   Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl,
150                                        const char *Name) {
151     if (Decl)
152       return Decl;
153
154     LLVMContext &C = TheModule->getContext();
155     Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
156     Type *I8XX = PointerType::getUnqual(I8X);
157     Type *Params[] = { I8XX, I8X };
158
159     AttributeSet Attr =
160       AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
161                                   Attribute::NoUnwind);
162     Attr = Attr.addAttribute(C, 1, Attribute::NoCapture);
163
164     FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
165                                           /*isVarArg=*/false);
166
167     return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
168   }
169
170 }; // class ARCRuntimeEntryPoints
171
172 } // namespace objcarc
173 } // namespace llvm
174
175 #endif // LLVM_TRANSFORMS_SCALAR_ARCRUNTIMEENTRYPOINTS_H