LLVM  9.0.0svn
ObjCARCInstKind.cpp
Go to the documentation of this file.
1 //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines several utility functions used by various ARC
10 /// optimizations which are IMHO too big to be in a header file.
11 ///
12 /// WARNING: This file knows about certain library functions. It recognizes them
13 /// by name, and hardwires knowledge of their semantics.
14 ///
15 /// WARNING: This file knows about how certain Objective-C library functions are
16 /// used. Naive LLVM IR transformations which would otherwise be
17 /// behavior-preserving may break these assumptions.
18 ///
19 //===----------------------------------------------------------------------===//
20 
22 #include "llvm/ADT/StringSwitch.h"
24 #include "llvm/IR/Intrinsics.h"
25 
26 using namespace llvm;
27 using namespace llvm::objcarc;
28 
30  const ARCInstKind Class) {
31  switch (Class) {
33  return OS << "ARCInstKind::Retain";
35  return OS << "ARCInstKind::RetainRV";
37  return OS << "ARCInstKind::ClaimRV";
39  return OS << "ARCInstKind::RetainBlock";
41  return OS << "ARCInstKind::Release";
43  return OS << "ARCInstKind::Autorelease";
45  return OS << "ARCInstKind::AutoreleaseRV";
47  return OS << "ARCInstKind::AutoreleasepoolPush";
49  return OS << "ARCInstKind::AutoreleasepoolPop";
51  return OS << "ARCInstKind::NoopCast";
53  return OS << "ARCInstKind::FusedRetainAutorelease";
55  return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
57  return OS << "ARCInstKind::LoadWeakRetained";
59  return OS << "ARCInstKind::StoreWeak";
61  return OS << "ARCInstKind::InitWeak";
63  return OS << "ARCInstKind::LoadWeak";
65  return OS << "ARCInstKind::MoveWeak";
67  return OS << "ARCInstKind::CopyWeak";
69  return OS << "ARCInstKind::DestroyWeak";
71  return OS << "ARCInstKind::StoreStrong";
73  return OS << "ARCInstKind::CallOrUser";
74  case ARCInstKind::Call:
75  return OS << "ARCInstKind::Call";
76  case ARCInstKind::User:
77  return OS << "ARCInstKind::User";
79  return OS << "ARCInstKind::IntrinsicUser";
80  case ARCInstKind::None:
81  return OS << "ARCInstKind::None";
82  }
83  llvm_unreachable("Unknown instruction class!");
84 }
85 
87 
89  switch (ID) {
90  default:
92  case Intrinsic::objc_autorelease:
94  case Intrinsic::objc_autoreleasePoolPop:
96  case Intrinsic::objc_autoreleasePoolPush:
98  case Intrinsic::objc_autoreleaseReturnValue:
100  case Intrinsic::objc_copyWeak:
101  return ARCInstKind::CopyWeak;
102  case Intrinsic::objc_destroyWeak:
104  case Intrinsic::objc_initWeak:
105  return ARCInstKind::InitWeak;
106  case Intrinsic::objc_loadWeak:
107  return ARCInstKind::LoadWeak;
108  case Intrinsic::objc_loadWeakRetained:
110  case Intrinsic::objc_moveWeak:
111  return ARCInstKind::MoveWeak;
112  case Intrinsic::objc_release:
113  return ARCInstKind::Release;
114  case Intrinsic::objc_retain:
115  return ARCInstKind::Retain;
116  case Intrinsic::objc_retainAutorelease:
118  case Intrinsic::objc_retainAutoreleaseReturnValue:
120  case Intrinsic::objc_retainAutoreleasedReturnValue:
121  return ARCInstKind::RetainRV;
122  case Intrinsic::objc_retainBlock:
124  case Intrinsic::objc_storeStrong:
126  case Intrinsic::objc_storeWeak:
127  return ARCInstKind::StoreWeak;
128  case Intrinsic::objc_clang_arc_use:
130  case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
131  return ARCInstKind::ClaimRV;
132  case Intrinsic::objc_retainedObject:
133  return ARCInstKind::NoopCast;
134  case Intrinsic::objc_unretainedObject:
135  return ARCInstKind::NoopCast;
136  case Intrinsic::objc_unretainedPointer:
137  return ARCInstKind::NoopCast;
138  case Intrinsic::objc_retain_autorelease:
140  case Intrinsic::objc_sync_enter:
141  return ARCInstKind::User;
142  case Intrinsic::objc_sync_exit:
143  return ARCInstKind::User;
144  case Intrinsic::objc_arc_annotation_topdown_bbstart:
145  case Intrinsic::objc_arc_annotation_topdown_bbend:
146  case Intrinsic::objc_arc_annotation_bottomup_bbstart:
147  case Intrinsic::objc_arc_annotation_bottomup_bbend:
148  // Ignore annotation calls. This is important to stop the
149  // optimizer from treating annotations as uses which would
150  // make the state of the pointers they are attempting to
151  // elucidate to be incorrect.
152  return ARCInstKind::None;
153  }
154 }
155 
156 // A whitelist of intrinsics that we know do not use objc pointers or decrement
157 // ref counts.
158 static bool isInertIntrinsic(unsigned ID) {
159  // TODO: Make this into a covered switch.
160  switch (ID) {
161  case Intrinsic::returnaddress:
162  case Intrinsic::addressofreturnaddress:
163  case Intrinsic::frameaddress:
164  case Intrinsic::stacksave:
165  case Intrinsic::stackrestore:
166  case Intrinsic::vastart:
167  case Intrinsic::vacopy:
168  case Intrinsic::vaend:
169  case Intrinsic::objectsize:
170  case Intrinsic::prefetch:
171  case Intrinsic::stackprotector:
172  case Intrinsic::eh_return_i32:
173  case Intrinsic::eh_return_i64:
174  case Intrinsic::eh_typeid_for:
175  case Intrinsic::eh_dwarf_cfa:
176  case Intrinsic::eh_sjlj_lsda:
177  case Intrinsic::eh_sjlj_functioncontext:
178  case Intrinsic::init_trampoline:
179  case Intrinsic::adjust_trampoline:
180  case Intrinsic::lifetime_start:
181  case Intrinsic::lifetime_end:
182  case Intrinsic::invariant_start:
183  case Intrinsic::invariant_end:
184  // Don't let dbg info affect our results.
185  case Intrinsic::dbg_declare:
186  case Intrinsic::dbg_value:
187  case Intrinsic::dbg_label:
188  // Short cut: Some intrinsics obviously don't use ObjC pointers.
189  return true;
190  default:
191  return false;
192  }
193 }
194 
195 // A whitelist of intrinsics that we know do not use objc pointers or decrement
196 // ref counts.
197 static bool isUseOnlyIntrinsic(unsigned ID) {
198  // We are conservative and even though intrinsics are unlikely to touch
199  // reference counts, we white list them for safety.
200  //
201  // TODO: Expand this into a covered switch. There is a lot more here.
202  switch (ID) {
203  case Intrinsic::memcpy:
204  case Intrinsic::memmove:
205  case Intrinsic::memset:
206  return true;
207  default:
208  return false;
209  }
210 }
211 
212 /// Determine what kind of construct V is.
214  if (const Instruction *I = dyn_cast<Instruction>(V)) {
215  // Any instruction other than bitcast and gep with a pointer operand have a
216  // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
217  // to a subsequent use, rather than using it themselves, in this sense.
218  // As a short cut, several other opcodes are known to have no pointer
219  // operands of interest. And ret is never followed by a release, so it's
220  // not interesting to examine.
221  switch (I->getOpcode()) {
222  case Instruction::Call: {
223  const CallInst *CI = cast<CallInst>(I);
224  // See if we have a function that we know something about.
225  if (const Function *F = CI->getCalledFunction()) {
226  ARCInstKind Class = GetFunctionClass(F);
227  if (Class != ARCInstKind::CallOrUser)
228  return Class;
229  Intrinsic::ID ID = F->getIntrinsicID();
230  if (isInertIntrinsic(ID))
231  return ARCInstKind::None;
232  if (isUseOnlyIntrinsic(ID))
233  return ARCInstKind::User;
234  }
235 
236  // Otherwise, be conservative.
237  return GetCallSiteClass(CI);
238  }
239  case Instruction::Invoke:
240  // Otherwise, be conservative.
241  return GetCallSiteClass(cast<InvokeInst>(I));
242  case Instruction::BitCast:
243  case Instruction::GetElementPtr:
244  case Instruction::Select:
245  case Instruction::PHI:
246  case Instruction::Ret:
247  case Instruction::Br:
248  case Instruction::Switch:
249  case Instruction::IndirectBr:
250  case Instruction::Alloca:
251  case Instruction::VAArg:
252  case Instruction::Add:
253  case Instruction::FAdd:
254  case Instruction::Sub:
255  case Instruction::FSub:
256  case Instruction::Mul:
257  case Instruction::FMul:
258  case Instruction::SDiv:
259  case Instruction::UDiv:
260  case Instruction::FDiv:
261  case Instruction::SRem:
262  case Instruction::URem:
263  case Instruction::FRem:
264  case Instruction::Shl:
265  case Instruction::LShr:
266  case Instruction::AShr:
267  case Instruction::And:
268  case Instruction::Or:
269  case Instruction::Xor:
270  case Instruction::SExt:
271  case Instruction::ZExt:
272  case Instruction::Trunc:
273  case Instruction::IntToPtr:
274  case Instruction::FCmp:
275  case Instruction::FPTrunc:
276  case Instruction::FPExt:
277  case Instruction::FPToUI:
278  case Instruction::FPToSI:
279  case Instruction::UIToFP:
280  case Instruction::SIToFP:
281  case Instruction::InsertElement:
282  case Instruction::ExtractElement:
283  case Instruction::ShuffleVector:
284  case Instruction::ExtractValue:
285  break;
286  case Instruction::ICmp:
287  // Comparing a pointer with null, or any other constant, isn't an
288  // interesting use, because we don't care what the pointer points to, or
289  // about the values of any other dynamic reference-counted pointers.
290  if (IsPotentialRetainableObjPtr(I->getOperand(1)))
291  return ARCInstKind::User;
292  break;
293  default:
294  // For anything else, check all the operands.
295  // Note that this includes both operands of a Store: while the first
296  // operand isn't actually being dereferenced, it is being stored to
297  // memory where we can no longer track who might read it and dereference
298  // it, so we have to consider it potentially used.
299  for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
300  OI != OE; ++OI)
302  return ARCInstKind::User;
303  }
304  }
305 
306  // Otherwise, it's totally inert for ARC purposes.
307  return ARCInstKind::None;
308 }
309 
310 /// Test if the given class is a kind of user.
312  switch (Class) {
313  case ARCInstKind::User:
316  return true;
317  case ARCInstKind::Retain:
336  case ARCInstKind::Call:
337  case ARCInstKind::None:
339  return false;
340  }
341  llvm_unreachable("covered switch isn't covered?");
342 }
343 
344 /// Test if the given class is objc_retain or equivalent.
346  switch (Class) {
347  case ARCInstKind::Retain:
349  return true;
350  // I believe we treat retain block as not a retain since it can copy its
351  // block.
371  case ARCInstKind::Call:
372  case ARCInstKind::User:
373  case ARCInstKind::None:
375  return false;
376  }
377  llvm_unreachable("covered switch isn't covered?");
378 }
379 
380 /// Test if the given class is objc_autorelease or equivalent.
382  switch (Class) {
385  return true;
386  case ARCInstKind::Retain:
406  case ARCInstKind::Call:
407  case ARCInstKind::User:
408  case ARCInstKind::None:
409  return false;
410  }
411  llvm_unreachable("covered switch isn't covered?");
412 }
413 
414 /// Test if the given class represents instructions which return their
415 /// argument verbatim.
417  switch (Class) {
418  case ARCInstKind::Retain:
424  return true;
441  case ARCInstKind::Call:
442  case ARCInstKind::User:
443  case ARCInstKind::None:
444  return false;
445  }
446  llvm_unreachable("covered switch isn't covered?");
447 }
448 
449 /// Test if the given class represents instructions which do nothing if
450 /// passed a null pointer.
452  switch (Class) {
453  case ARCInstKind::Retain:
460  return true;
475  case ARCInstKind::Call:
476  case ARCInstKind::User:
477  case ARCInstKind::None:
479  return false;
480  }
481  llvm_unreachable("covered switch isn't covered?");
482 }
483 
484 /// Test if the given class represents instructions which are always safe
485 /// to mark with the "tail" keyword.
487  // ARCInstKind::RetainBlock may be given a stack argument.
488  switch (Class) {
489  case ARCInstKind::Retain:
493  return true;
511  case ARCInstKind::Call:
512  case ARCInstKind::User:
513  case ARCInstKind::None:
515  return false;
516  }
517  llvm_unreachable("covered switch isn't covered?");
518 }
519 
520 /// Test if the given class represents instructions which are never safe
521 /// to mark with the "tail" keyword.
523  /// It is never safe to tail call objc_autorelease since by tail calling
524  /// objc_autorelease: fast autoreleasing causing our object to be potentially
525  /// reclaimed from the autorelease pool which violates the semantics of
526  /// __autoreleasing types in ARC.
527  switch (Class) {
529  return true;
530  case ARCInstKind::Retain:
550  case ARCInstKind::Call:
551  case ARCInstKind::User:
552  case ARCInstKind::None:
554  return false;
555  }
556  llvm_unreachable("covered switch isn't covered?");
557 }
558 
559 /// Test if the given class represents instructions which are always safe
560 /// to mark with the nounwind attribute.
562  // objc_retainBlock is not nounwind because it calls user copy constructors
563  // which could theoretically throw.
564  switch (Class) {
565  case ARCInstKind::Retain:
573  return true;
587  case ARCInstKind::Call:
588  case ARCInstKind::User:
589  case ARCInstKind::None:
591  return false;
592  }
593  llvm_unreachable("covered switch isn't covered?");
594 }
595 
596 /// Test whether the given instruction can autorelease any pointer or cause an
597 /// autoreleasepool pop.
598 ///
599 /// This means that it *could* interrupt the RV optimization.
601  switch (Class) {
604  case ARCInstKind::Call:
609  return true;
610  case ARCInstKind::Retain:
625  case ARCInstKind::User:
626  case ARCInstKind::None:
628  return false;
629  }
630  llvm_unreachable("covered switch isn't covered?");
631 }
632 
634  switch (Kind) {
635  case ARCInstKind::Retain:
643  case ARCInstKind::User:
644  case ARCInstKind::None:
645  return false;
646 
647  // The cases below are conservative.
648 
649  // RetainBlock can result in user defined copy constructors being called
650  // implying releases may occur.
664  case ARCInstKind::Call:
666  return true;
667  }
668 
669  llvm_unreachable("covered switch isn't covered?");
670 }
ARCInstKind GetARCInstKind(const Value *V)
Map V to its ARCInstKind equivalence class.
objc_destroyWeak (derived)
bool IsUser(ARCInstKind Class)
Test if the given class is a kind of user.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
objc_loadWeakRetained (primitive)
could call objc_release and/or "use" pointers
objc_loadWeak (derived)
This class represents a function call, abstracting a target machine&#39;s calling convention.
objc_retainedObject, etc.
F(f)
could call objc_release
loop data prefetch
objc_moveWeak (derived)
bool IsNoopOnNull(ARCInstKind Class)
Test if the given class represents instructions which do nothing if passed a null pointer...
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
objc_autoreleaseReturnValue
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
objc_retainAutoreleasedReturnValue
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
raw_ostream & operator<<(raw_ostream &OS, const ARCInstKind Class)
objc_initWeak (derived)
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
objc_copyWeak (derived)
This file defines common analysis utilities used by the ObjC ARC Optimizer.
anything that is inert from an ARC perspective.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool CanDecrementRefCount(ARCInstKind Kind)
Returns false if conservatively we can prove that any instruction mapped to this kind can not decreme...
static bool isInertIntrinsic(unsigned ID)
ARCInstKind
Equivalence classes of instructions in the ARC Model.
bool IsNoThrow(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the nounwind attri...
objc_unsafeClaimAutoreleasedReturnValue
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:193
objc_storeStrong (derived)
could "use" a pointer
bool IsRetain(ARCInstKind Class)
Test if the given class is objc_retain or equivalent.
static bool isUseOnlyIntrinsic(unsigned ID)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1201
#define I(x, y, z)
Definition: MD5.cpp:58
objc_storeWeak (primitive)
ARCInstKind GetCallSiteClass(ImmutableCallSite CS)
Helper for GetARCInstKind.
LLVM Value Representation.
Definition: Value.h:72
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
bool CanInterruptRV(ARCInstKind Class)
Test whether the given instruction can autorelease any pointer or cause an autoreleasepool pop...
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword...
bool IsAutorelease(ARCInstKind Class)
Test if the given class is objc_autorelease or equivalent.