LLVM  13.0.0git
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 
23 #include "llvm/IR/Intrinsics.h"
24 
25 using namespace llvm;
26 using namespace llvm::objcarc;
27 
29  const ARCInstKind Class) {
30  switch (Class) {
32  return OS << "ARCInstKind::Retain";
34  return OS << "ARCInstKind::RetainRV";
36  return OS << "ARCInstKind::ClaimRV";
38  return OS << "ARCInstKind::RetainBlock";
40  return OS << "ARCInstKind::Release";
42  return OS << "ARCInstKind::Autorelease";
44  return OS << "ARCInstKind::AutoreleaseRV";
46  return OS << "ARCInstKind::AutoreleasepoolPush";
48  return OS << "ARCInstKind::AutoreleasepoolPop";
50  return OS << "ARCInstKind::NoopCast";
52  return OS << "ARCInstKind::FusedRetainAutorelease";
54  return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
56  return OS << "ARCInstKind::LoadWeakRetained";
58  return OS << "ARCInstKind::StoreWeak";
60  return OS << "ARCInstKind::InitWeak";
62  return OS << "ARCInstKind::LoadWeak";
64  return OS << "ARCInstKind::MoveWeak";
66  return OS << "ARCInstKind::CopyWeak";
68  return OS << "ARCInstKind::DestroyWeak";
70  return OS << "ARCInstKind::StoreStrong";
72  return OS << "ARCInstKind::CallOrUser";
73  case ARCInstKind::Call:
74  return OS << "ARCInstKind::Call";
75  case ARCInstKind::User:
76  return OS << "ARCInstKind::User";
78  return OS << "ARCInstKind::IntrinsicUser";
79  case ARCInstKind::None:
80  return OS << "ARCInstKind::None";
81  }
82  llvm_unreachable("Unknown instruction class!");
83 }
84 
86 
87  Intrinsic::ID ID = F->getIntrinsicID();
88  switch (ID) {
89  default:
91  case Intrinsic::objc_autorelease:
93  case Intrinsic::objc_autoreleasePoolPop:
95  case Intrinsic::objc_autoreleasePoolPush:
97  case Intrinsic::objc_autoreleaseReturnValue:
99  case Intrinsic::objc_copyWeak:
100  return ARCInstKind::CopyWeak;
101  case Intrinsic::objc_destroyWeak:
103  case Intrinsic::objc_initWeak:
104  return ARCInstKind::InitWeak;
105  case Intrinsic::objc_loadWeak:
106  return ARCInstKind::LoadWeak;
107  case Intrinsic::objc_loadWeakRetained:
109  case Intrinsic::objc_moveWeak:
110  return ARCInstKind::MoveWeak;
111  case Intrinsic::objc_release:
112  return ARCInstKind::Release;
113  case Intrinsic::objc_retain:
114  return ARCInstKind::Retain;
115  case Intrinsic::objc_retainAutorelease:
117  case Intrinsic::objc_retainAutoreleaseReturnValue:
119  case Intrinsic::objc_retainAutoreleasedReturnValue:
120  return ARCInstKind::RetainRV;
121  case Intrinsic::objc_retainBlock:
123  case Intrinsic::objc_storeStrong:
125  case Intrinsic::objc_storeWeak:
126  return ARCInstKind::StoreWeak;
127  case Intrinsic::objc_clang_arc_use:
129  case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
130  return ARCInstKind::ClaimRV;
131  case Intrinsic::objc_retainedObject:
132  return ARCInstKind::NoopCast;
133  case Intrinsic::objc_unretainedObject:
134  return ARCInstKind::NoopCast;
135  case Intrinsic::objc_unretainedPointer:
136  return ARCInstKind::NoopCast;
137  case Intrinsic::objc_retain_autorelease:
139  case Intrinsic::objc_sync_enter:
140  return ARCInstKind::User;
141  case Intrinsic::objc_sync_exit:
142  return ARCInstKind::User;
143  case Intrinsic::objc_clang_arc_noop_use:
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 list 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 list 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 do nothing if
485 /// passed a global variable.
487  switch (Class) {
488  case ARCInstKind::Retain:
497  return true;
510  case ARCInstKind::Call:
511  case ARCInstKind::User:
512  case ARCInstKind::None:
514  return false;
515  }
516  llvm_unreachable("covered switch isn't covered?");
517 }
518 
519 /// Test if the given class represents instructions which are always safe
520 /// to mark with the "tail" keyword.
522  // ARCInstKind::RetainBlock may be given a stack argument.
523  switch (Class) {
524  case ARCInstKind::Retain:
528  return true;
546  case ARCInstKind::Call:
547  case ARCInstKind::User:
548  case ARCInstKind::None:
550  return false;
551  }
552  llvm_unreachable("covered switch isn't covered?");
553 }
554 
555 /// Test if the given class represents instructions which are never safe
556 /// to mark with the "tail" keyword.
558  /// It is never safe to tail call objc_autorelease since by tail calling
559  /// objc_autorelease: fast autoreleasing causing our object to be potentially
560  /// reclaimed from the autorelease pool which violates the semantics of
561  /// __autoreleasing types in ARC.
562  switch (Class) {
564  return true;
565  case ARCInstKind::Retain:
585  case ARCInstKind::Call:
586  case ARCInstKind::User:
587  case ARCInstKind::None:
589  return false;
590  }
591  llvm_unreachable("covered switch isn't covered?");
592 }
593 
594 /// Test if the given class represents instructions which are always safe
595 /// to mark with the nounwind attribute.
597  // objc_retainBlock is not nounwind because it calls user copy constructors
598  // which could theoretically throw.
599  switch (Class) {
600  case ARCInstKind::Retain:
608  return true;
622  case ARCInstKind::Call:
623  case ARCInstKind::User:
624  case ARCInstKind::None:
626  return false;
627  }
628  llvm_unreachable("covered switch isn't covered?");
629 }
630 
631 /// Test whether the given instruction can autorelease any pointer or cause an
632 /// autoreleasepool pop.
633 ///
634 /// This means that it *could* interrupt the RV optimization.
636  switch (Class) {
639  case ARCInstKind::Call:
644  return true;
645  case ARCInstKind::Retain:
660  case ARCInstKind::User:
661  case ARCInstKind::None:
663  return false;
664  }
665  llvm_unreachable("covered switch isn't covered?");
666 }
667 
669  switch (Kind) {
670  case ARCInstKind::Retain:
678  case ARCInstKind::User:
679  case ARCInstKind::None:
680  return false;
681 
682  // The cases below are conservative.
683 
684  // RetainBlock can result in user defined copy constructors being called
685  // implying releases may occur.
699  case ARCInstKind::Call:
701  return true;
702  }
703 
704  llvm_unreachable("covered switch isn't covered?");
705 }
llvm::objcarc::ARCInstKind::User
@ User
could "use" a pointer
llvm::objcarc::operator<<
raw_ostream & operator<<(raw_ostream &OS, const ARCInstKind Class)
Definition: ObjCARCInstKind.cpp:28
llvm
Definition: AllocatorList.h:23
llvm::Function
Definition: Function.h:61
llvm::objcarc::ARCInstKind::RetainBlock
@ RetainBlock
objc_retainBlock
llvm::objcarc::GetFunctionClass
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
Definition: ObjCARCInstKind.cpp:85
llvm::objcarc::IsNeverTail
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
Definition: ObjCARCInstKind.cpp:557
llvm::objcarc::ARCInstKind::LoadWeak
@ LoadWeak
objc_loadWeak (derived)
llvm::objcarc::ARCInstKind::Call
@ Call
could call objc_release
isInertIntrinsic
static bool isInertIntrinsic(unsigned ID)
Definition: ObjCARCInstKind.cpp:158
llvm::objcarc::ARCInstKind::MoveWeak
@ MoveWeak
objc_moveWeak (derived)
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::objcarc::GetARCInstKind
ARCInstKind GetARCInstKind(const Value *V)
Map V to its ARCInstKind equivalence class.
Definition: ObjCARCInstKind.cpp:213
llvm::objcarc::IsAutorelease
bool IsAutorelease(ARCInstKind Class)
Test if the given class is objc_autorelease or equivalent.
Definition: ObjCARCInstKind.cpp:381
llvm::objcarc::ARCInstKind::Autorelease
@ Autorelease
objc_autorelease
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::objcarc::CanInterruptRV
bool CanInterruptRV(ARCInstKind Class)
Test whether the given instruction can autorelease any pointer or cause an autoreleasepool pop.
Definition: ObjCARCInstKind.cpp:635
llvm::objcarc::IsPotentialRetainableObjPtr
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
Definition: ObjCARCAnalysisUtils.h:143
llvm::objcarc::ARCInstKind::InitWeak
@ InitWeak
objc_initWeak (derived)
isUseOnlyIntrinsic
static bool isUseOnlyIntrinsic(unsigned ID)
Definition: ObjCARCInstKind.cpp:197
Intrinsics.h
llvm::objcarc::ARCInstKind::CallOrUser
@ CallOrUser
could call objc_release and/or "use" pointers
llvm::objcarc::IsNoopOnGlobal
bool IsNoopOnGlobal(ARCInstKind Class)
Test if the given class represents instructions which do nothing if passed a global variable.
Definition: ObjCARCInstKind.cpp:486
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1396
llvm::objcarc::ARCInstKind::Release
@ Release
objc_release
llvm::objcarc::ARCInstKind::RetainRV
@ RetainRV
objc_retainAutoreleasedReturnValue
llvm::objcarc::ARCInstKind::NoopCast
@ NoopCast
objc_retainedObject, etc.
llvm::objcarc::ARCInstKind::CopyWeak
@ CopyWeak
objc_copyWeak (derived)
llvm::Instruction
Definition: Instruction.h:45
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
llvm::objcarc::ARCInstKind::IntrinsicUser
@ IntrinsicUser
llvm.objc.clang.arc.use
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:153
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::objcarc::ARCInstKind
ARCInstKind
Definition: ObjCARCInstKind.h:28
llvm::objcarc::IsAlwaysTail
bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
Definition: ObjCARCInstKind.cpp:521
llvm::objcarc::ARCInstKind::AutoreleasepoolPop
@ AutoreleasepoolPop
objc_autoreleasePoolPop
llvm::objcarc::IsNoThrow
bool IsNoThrow(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the nounwind attri...
Definition: ObjCARCInstKind.cpp:596
llvm::objcarc::ARCInstKind::FusedRetainAutorelease
@ FusedRetainAutorelease
objc_retainAutorelease
I
#define I(x, y, z)
Definition: MD5.cpp:59
ObjCARCInstKind.h
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::objcarc::IsRetain
bool IsRetain(ARCInstKind Class)
Test if the given class is objc_retain or equivalent.
Definition: ObjCARCInstKind.cpp:345
llvm::objcarc
Definition: ObjCARCAliasAnalysis.h:29
prefetch
loop data prefetch
Definition: LoopDataPrefetch.cpp:146
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
ObjCARCAnalysisUtils.h
llvm::objcarc::ARCInstKind::AutoreleasepoolPush
@ AutoreleasepoolPush
objc_autoreleasePoolPush
llvm::MCID::Select
@ Select
Definition: MCInstrDesc.h:162
llvm::objcarc::ARCInstKind::StoreWeak
@ StoreWeak
objc_storeWeak (primitive)
llvm::objcarc::ARCInstKind::FusedRetainAutoreleaseRV
@ FusedRetainAutoreleaseRV
objc_retainAutoreleaseReturnValue
llvm::objcarc::ARCInstKind::DestroyWeak
@ DestroyWeak
objc_destroyWeak (derived)
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:183
llvm::objcarc::GetCallSiteClass
ARCInstKind GetCallSiteClass(const CallBase &CB)
Helper for GetARCInstKind.
Definition: ObjCARCAnalysisUtils.h:170
llvm::objcarc::ARCInstKind::StoreStrong
@ StoreStrong
objc_storeStrong (derived)
llvm::objcarc::CanDecrementRefCount
bool CanDecrementRefCount(ARCInstKind Kind)
Returns false if conservatively we can prove that any instruction mapped to this kind can not decreme...
Definition: ObjCARCInstKind.cpp:668
llvm::objcarc::ARCInstKind::ClaimRV
@ ClaimRV
objc_unsafeClaimAutoreleasedReturnValue
llvm::objcarc::ARCInstKind::None
@ None
anything that is inert from an ARC perspective.
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1450
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::objcarc::ARCInstKind::Retain
@ Retain
objc_retain
llvm::objcarc::IsForwarding
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
Definition: ObjCARCInstKind.cpp:416
llvm::objcarc::IsNoopOnNull
bool IsNoopOnNull(ARCInstKind Class)
Test if the given class represents instructions which do nothing if passed a null pointer.
Definition: ObjCARCInstKind.cpp:451
llvm::objcarc::ARCInstKind::LoadWeakRetained
@ LoadWeakRetained
objc_loadWeakRetained (primitive)
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::objcarc::IsUser
bool IsUser(ARCInstKind Class)
Test if the given class is a kind of user.
Definition: ObjCARCInstKind.cpp:311
llvm::objcarc::ARCInstKind::AutoreleaseRV
@ AutoreleaseRV
objc_autoreleaseReturnValue
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38