1 //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file defines several utility functions used by various ARC
11 /// optimizations which are IMHO too big to be in a header file.
13 /// WARNING: This file knows about certain library functions. It recognizes them
14 /// by name, and hardwires knowledge of their semantics.
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.
20 //===----------------------------------------------------------------------===//
23 #include "llvm/IR/Intrinsics.h"
26 using namespace llvm::objcarc;
28 raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
29 const ARCInstKind Class) {
31 case ARCInstKind::Retain:
32 return OS << "ARCInstKind::Retain";
33 case ARCInstKind::RetainRV:
34 return OS << "ARCInstKind::RetainRV";
35 case ARCInstKind::RetainBlock:
36 return OS << "ARCInstKind::RetainBlock";
37 case ARCInstKind::Release:
38 return OS << "ARCInstKind::Release";
39 case ARCInstKind::Autorelease:
40 return OS << "ARCInstKind::Autorelease";
41 case ARCInstKind::AutoreleaseRV:
42 return OS << "ARCInstKind::AutoreleaseRV";
43 case ARCInstKind::AutoreleasepoolPush:
44 return OS << "ARCInstKind::AutoreleasepoolPush";
45 case ARCInstKind::AutoreleasepoolPop:
46 return OS << "ARCInstKind::AutoreleasepoolPop";
47 case ARCInstKind::NoopCast:
48 return OS << "ARCInstKind::NoopCast";
49 case ARCInstKind::FusedRetainAutorelease:
50 return OS << "ARCInstKind::FusedRetainAutorelease";
51 case ARCInstKind::FusedRetainAutoreleaseRV:
52 return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
53 case ARCInstKind::LoadWeakRetained:
54 return OS << "ARCInstKind::LoadWeakRetained";
55 case ARCInstKind::StoreWeak:
56 return OS << "ARCInstKind::StoreWeak";
57 case ARCInstKind::InitWeak:
58 return OS << "ARCInstKind::InitWeak";
59 case ARCInstKind::LoadWeak:
60 return OS << "ARCInstKind::LoadWeak";
61 case ARCInstKind::MoveWeak:
62 return OS << "ARCInstKind::MoveWeak";
63 case ARCInstKind::CopyWeak:
64 return OS << "ARCInstKind::CopyWeak";
65 case ARCInstKind::DestroyWeak:
66 return OS << "ARCInstKind::DestroyWeak";
67 case ARCInstKind::StoreStrong:
68 return OS << "ARCInstKind::StoreStrong";
69 case ARCInstKind::CallOrUser:
70 return OS << "ARCInstKind::CallOrUser";
71 case ARCInstKind::Call:
72 return OS << "ARCInstKind::Call";
73 case ARCInstKind::User:
74 return OS << "ARCInstKind::User";
75 case ARCInstKind::IntrinsicUser:
76 return OS << "ARCInstKind::IntrinsicUser";
77 case ARCInstKind::None:
78 return OS << "ARCInstKind::None";
80 llvm_unreachable("Unknown instruction class!");
83 ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
84 Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
86 // No (mandatory) arguments.
88 return StringSwitch<ARCInstKind>(F->getName())
89 .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush)
90 .Case("clang.arc.use", ARCInstKind::IntrinsicUser)
91 .Default(ARCInstKind::CallOrUser);
94 const Argument *A0 = AI++;
96 // Argument is a pointer.
97 if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
98 Type *ETy = PTy->getElementType();
100 if (ETy->isIntegerTy(8))
101 return StringSwitch<ARCInstKind>(F->getName())
102 .Case("objc_retain", ARCInstKind::Retain)
103 .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV)
104 .Case("objc_retainBlock", ARCInstKind::RetainBlock)
105 .Case("objc_release", ARCInstKind::Release)
106 .Case("objc_autorelease", ARCInstKind::Autorelease)
107 .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV)
108 .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop)
109 .Case("objc_retainedObject", ARCInstKind::NoopCast)
110 .Case("objc_unretainedObject", ARCInstKind::NoopCast)
111 .Case("objc_unretainedPointer", ARCInstKind::NoopCast)
112 .Case("objc_retain_autorelease",
113 ARCInstKind::FusedRetainAutorelease)
114 .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease)
115 .Case("objc_retainAutoreleaseReturnValue",
116 ARCInstKind::FusedRetainAutoreleaseRV)
117 .Case("objc_sync_enter", ARCInstKind::User)
118 .Case("objc_sync_exit", ARCInstKind::User)
119 .Default(ARCInstKind::CallOrUser);
122 if (PointerType *Pte = dyn_cast<PointerType>(ETy))
123 if (Pte->getElementType()->isIntegerTy(8))
124 return StringSwitch<ARCInstKind>(F->getName())
125 .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained)
126 .Case("objc_loadWeak", ARCInstKind::LoadWeak)
127 .Case("objc_destroyWeak", ARCInstKind::DestroyWeak)
128 .Default(ARCInstKind::CallOrUser);
131 // Two arguments, first is i8**.
132 const Argument *A1 = AI++;
134 if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
135 if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
136 if (Pte->getElementType()->isIntegerTy(8))
137 if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
138 Type *ETy1 = PTy1->getElementType();
139 // Second argument is i8*
140 if (ETy1->isIntegerTy(8))
141 return StringSwitch<ARCInstKind>(F->getName())
142 .Case("objc_storeWeak", ARCInstKind::StoreWeak)
143 .Case("objc_initWeak", ARCInstKind::InitWeak)
144 .Case("objc_storeStrong", ARCInstKind::StoreStrong)
145 .Default(ARCInstKind::CallOrUser);
146 // Second argument is i8**.
147 if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
148 if (Pte1->getElementType()->isIntegerTy(8))
149 return StringSwitch<ARCInstKind>(F->getName())
150 .Case("objc_moveWeak", ARCInstKind::MoveWeak)
151 .Case("objc_copyWeak", ARCInstKind::CopyWeak)
152 // Ignore annotation calls. This is important to stop the
153 // optimizer from treating annotations as uses which would
154 // make the state of the pointers they are attempting to
155 // elucidate to be incorrect.
156 .Case("llvm.arc.annotation.topdown.bbstart",
158 .Case("llvm.arc.annotation.topdown.bbend",
160 .Case("llvm.arc.annotation.bottomup.bbstart",
162 .Case("llvm.arc.annotation.bottomup.bbend",
164 .Default(ARCInstKind::CallOrUser);
168 return ARCInstKind::CallOrUser;
171 /// \brief Determine what kind of construct V is.
172 ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
173 if (const Instruction *I = dyn_cast<Instruction>(V)) {
174 // Any instruction other than bitcast and gep with a pointer operand have a
175 // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
176 // to a subsequent use, rather than using it themselves, in this sense.
177 // As a short cut, several other opcodes are known to have no pointer
178 // operands of interest. And ret is never followed by a release, so it's
179 // not interesting to examine.
180 switch (I->getOpcode()) {
181 case Instruction::Call: {
182 const CallInst *CI = cast<CallInst>(I);
183 // Check for calls to special functions.
184 if (const Function *F = CI->getCalledFunction()) {
185 ARCInstKind Class = GetFunctionClass(F);
186 if (Class != ARCInstKind::CallOrUser)
189 // None of the intrinsic functions do objc_release. For intrinsics, the
190 // only question is whether or not they may be users.
191 switch (F->getIntrinsicID()) {
192 case Intrinsic::returnaddress:
193 case Intrinsic::frameaddress:
194 case Intrinsic::stacksave:
195 case Intrinsic::stackrestore:
196 case Intrinsic::vastart:
197 case Intrinsic::vacopy:
198 case Intrinsic::vaend:
199 case Intrinsic::objectsize:
200 case Intrinsic::prefetch:
201 case Intrinsic::stackprotector:
202 case Intrinsic::eh_return_i32:
203 case Intrinsic::eh_return_i64:
204 case Intrinsic::eh_typeid_for:
205 case Intrinsic::eh_dwarf_cfa:
206 case Intrinsic::eh_sjlj_lsda:
207 case Intrinsic::eh_sjlj_functioncontext:
208 case Intrinsic::init_trampoline:
209 case Intrinsic::adjust_trampoline:
210 case Intrinsic::lifetime_start:
211 case Intrinsic::lifetime_end:
212 case Intrinsic::invariant_start:
213 case Intrinsic::invariant_end:
214 // Don't let dbg info affect our results.
215 case Intrinsic::dbg_declare:
216 case Intrinsic::dbg_value:
217 // Short cut: Some intrinsics obviously don't use ObjC pointers.
218 return ARCInstKind::None;
223 return GetCallSiteClass(CI);
225 case Instruction::Invoke:
226 return GetCallSiteClass(cast<InvokeInst>(I));
227 case Instruction::BitCast:
228 case Instruction::GetElementPtr:
229 case Instruction::Select:
230 case Instruction::PHI:
231 case Instruction::Ret:
232 case Instruction::Br:
233 case Instruction::Switch:
234 case Instruction::IndirectBr:
235 case Instruction::Alloca:
236 case Instruction::VAArg:
237 case Instruction::Add:
238 case Instruction::FAdd:
239 case Instruction::Sub:
240 case Instruction::FSub:
241 case Instruction::Mul:
242 case Instruction::FMul:
243 case Instruction::SDiv:
244 case Instruction::UDiv:
245 case Instruction::FDiv:
246 case Instruction::SRem:
247 case Instruction::URem:
248 case Instruction::FRem:
249 case Instruction::Shl:
250 case Instruction::LShr:
251 case Instruction::AShr:
252 case Instruction::And:
253 case Instruction::Or:
254 case Instruction::Xor:
255 case Instruction::SExt:
256 case Instruction::ZExt:
257 case Instruction::Trunc:
258 case Instruction::IntToPtr:
259 case Instruction::FCmp:
260 case Instruction::FPTrunc:
261 case Instruction::FPExt:
262 case Instruction::FPToUI:
263 case Instruction::FPToSI:
264 case Instruction::UIToFP:
265 case Instruction::SIToFP:
266 case Instruction::InsertElement:
267 case Instruction::ExtractElement:
268 case Instruction::ShuffleVector:
269 case Instruction::ExtractValue:
271 case Instruction::ICmp:
272 // Comparing a pointer with null, or any other constant, isn't an
273 // interesting use, because we don't care what the pointer points to, or
274 // about the values of any other dynamic reference-counted pointers.
275 if (IsPotentialRetainableObjPtr(I->getOperand(1)))
276 return ARCInstKind::User;
279 // For anything else, check all the operands.
280 // Note that this includes both operands of a Store: while the first
281 // operand isn't actually being dereferenced, it is being stored to
282 // memory where we can no longer track who might read it and dereference
283 // it, so we have to consider it potentially used.
284 for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
286 if (IsPotentialRetainableObjPtr(*OI))
287 return ARCInstKind::User;
291 // Otherwise, it's totally inert for ARC purposes.
292 return ARCInstKind::None;