1//===- ObjCARCOpts.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//
9/// \file
10/// This file defines ObjC ARC optimizations. ARC stands for Automatic
11/// Reference Counting and is a system for managing reference counts for objects
12/// in Objective C.
13///
14/// The optimizations performed include elimination of redundant, partially
15/// redundant, and inconsequential reference count operations, elimination of
16/// redundant weak pointer operations, and numerous minor simplifications.
17///
18/// WARNING: This file knows about certain library functions. It recognizes them
19/// by name, and hardwires knowledge of their semantics.
20///
21/// WARNING: This file knows about how certain Objective-C library functions are
22/// used. Naive LLVM IR transformations which would otherwise be
23/// behavior-preserving may break these assumptions.
24//
25//===----------------------------------------------------------------------===//
26
27#include "ARCRuntimeEntryPoints.h"
28#include "BlotMapVector.h"
29#include "DependencyAnalysis.h"
30#include "ObjCARC.h"
31#include "ProvenanceAnalysis.h"
32#include "PtrState.h"
33#include "llvm/ADT/DenseMap.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/ADT/SmallPtrSet.h"
36#include "llvm/ADT/SmallVector.h"
37#include "llvm/ADT/Statistic.h"
38#include "llvm/Analysis/AliasAnalysis.h"
39#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
40#include "llvm/Analysis/ObjCARCInstKind.h"
41#include "llvm/Analysis/ObjCARCUtil.h"
42#include "llvm/Analysis/OptimizationRemarkEmitter.h"
43#include "llvm/IR/BasicBlock.h"
44#include "llvm/IR/CFG.h"
45#include "llvm/IR/Constant.h"
46#include "llvm/IR/Constants.h"
47#include "llvm/IR/DerivedTypes.h"
48#include "llvm/IR/EHPersonalities.h"
49#include "llvm/IR/Function.h"
50#include "llvm/IR/GlobalVariable.h"
51#include "llvm/IR/InstIterator.h"
52#include "llvm/IR/InstrTypes.h"
53#include "llvm/IR/Instruction.h"
54#include "llvm/IR/Instructions.h"
55#include "llvm/IR/LLVMContext.h"
56#include "llvm/IR/Metadata.h"
57#include "llvm/IR/Type.h"
58#include "llvm/IR/User.h"
59#include "llvm/IR/Value.h"
60#include "llvm/Support/Casting.h"
61#include "llvm/Support/CommandLine.h"
62#include "llvm/Support/Compiler.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/ErrorHandling.h"
65#include "llvm/Support/raw_ostream.h"
66#include "llvm/Transforms/ObjCARC.h"
67#include <cassert>
68#include <iterator>
69#include <utility>
70
71using namespace llvm;
72using namespace llvm::objcarc;
73
74#define DEBUG_TYPE "objc-arc-opts"
75
76static cl::opt<unsigned> MaxPtrStates("arc-opt-max-ptr-states",
77 cl::Hidden,
78 cl::desc("Maximum number of ptr states the optimizer keeps track of"),
79 cl::init(Val: 4095));
80
81/// \defgroup ARCUtilities Utility declarations/definitions specific to ARC.
82/// @{
83
84/// This is similar to GetRCIdentityRoot but it stops as soon
85/// as it finds a value with multiple uses.
86static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
87 // ConstantData (like ConstantPointerNull and UndefValue) is used across
88 // modules. It's never a single-use value.
89 if (isa<ConstantData>(Val: Arg))
90 return nullptr;
91
92 if (Arg->hasOneUse()) {
93 if (const BitCastInst *BC = dyn_cast<BitCastInst>(Val: Arg))
94 return FindSingleUseIdentifiedObject(Arg: BC->getOperand(i_nocapture: 0));
95 if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Val: Arg))
96 if (GEP->hasAllZeroIndices())
97 return FindSingleUseIdentifiedObject(Arg: GEP->getPointerOperand());
98 if (IsForwarding(Class: GetBasicARCInstKind(V: Arg)))
99 return FindSingleUseIdentifiedObject(
100 Arg: cast<CallInst>(Val: Arg)->getArgOperand(i: 0));
101 if (!IsObjCIdentifiedObject(V: Arg))
102 return nullptr;
103 return Arg;
104 }
105
106 // If we found an identifiable object but it has multiple uses, but they are
107 // trivial uses, we can still consider this to be a single-use value.
108 if (IsObjCIdentifiedObject(V: Arg)) {
109 for (const User *U : Arg->users())
110 if (!U->use_empty() || GetRCIdentityRoot(V: U) != Arg)
111 return nullptr;
112
113 return Arg;
114 }
115
116 return nullptr;
117}
118
119/// @}
120///
121/// \defgroup ARCOpt ARC Optimization.
122/// @{
123
124// TODO: On code like this:
125//
126// objc_retain(%x)
127// stuff_that_cannot_release()
128// objc_autorelease(%x)
129// stuff_that_cannot_release()
130// objc_retain(%x)
131// stuff_that_cannot_release()
132// objc_autorelease(%x)
133//
134// The second retain and autorelease can be deleted.
135
136// TODO: Critical-edge splitting. If the optimial insertion point is
137// a critical edge, the current algorithm has to fail, because it doesn't
138// know how to split edges. It should be possible to make the optimizer
139// think in terms of edges, rather than blocks, and then split critical
140// edges on demand.
141
142// TODO: OptimizeSequences could generalized to be Interprocedural.
143
144// TODO: Recognize that a bunch of other objc runtime calls have
145// non-escaping arguments and non-releasing arguments, and may be
146// non-autoreleasing.
147
148// TODO: Sink autorelease calls as far as possible. Unfortunately we
149// usually can't sink them past other calls, which would be the main
150// case where it would be useful.
151
152// TODO: The pointer returned from objc_loadWeakRetained is retained.
153
154// TODO: Delete release+retain pairs (rare).
155
156STATISTIC(NumNoops, "Number of no-op objc calls eliminated");
157STATISTIC(NumPartialNoops, "Number of partially no-op objc calls eliminated");
158STATISTIC(NumAutoreleases,"Number of autoreleases converted to releases");
159STATISTIC(NumRets, "Number of return value forwarding "
160 "retain+autoreleases eliminated");
161STATISTIC(NumRRs, "Number of retain+release paths eliminated");
162STATISTIC(NumPeeps, "Number of calls peephole-optimized");
163#ifndef NDEBUG
164STATISTIC(NumRetainsBeforeOpt,
165 "Number of retains before optimization");
166STATISTIC(NumReleasesBeforeOpt,
167 "Number of releases before optimization");
168STATISTIC(NumRetainsAfterOpt,
169 "Number of retains after optimization");
170STATISTIC(NumReleasesAfterOpt,
171 "Number of releases after optimization");
172#endif
173
174namespace {
175
176 /// Per-BasicBlock state.
177 class BBState {
178 /// The number of unique control paths from the entry which can reach this
179 /// block.
180 unsigned TopDownPathCount = 0;
181
182 /// The number of unique control paths to exits from this block.
183 unsigned BottomUpPathCount = 0;
184
185 /// The top-down traversal uses this to record information known about a
186 /// pointer at the bottom of each block.
187 BlotMapVector<const Value *, TopDownPtrState> PerPtrTopDown;
188
189 /// The bottom-up traversal uses this to record information known about a
190 /// pointer at the top of each block.
191 BlotMapVector<const Value *, BottomUpPtrState> PerPtrBottomUp;
192
193 /// Effective predecessors of the current block ignoring ignorable edges and
194 /// ignored backedges.
195 SmallVector<BasicBlock *, 2> Preds;
196
197 /// Effective successors of the current block ignoring ignorable edges and
198 /// ignored backedges.
199 SmallVector<BasicBlock *, 2> Succs;
200
201 public:
202 static const unsigned OverflowOccurredValue;
203
204 BBState() = default;
205
206 using top_down_ptr_iterator = decltype(PerPtrTopDown)::iterator;
207 using const_top_down_ptr_iterator = decltype(PerPtrTopDown)::const_iterator;
208
209 top_down_ptr_iterator top_down_ptr_begin() { return PerPtrTopDown.begin(); }
210 top_down_ptr_iterator top_down_ptr_end() { return PerPtrTopDown.end(); }
211 const_top_down_ptr_iterator top_down_ptr_begin() const {
212 return PerPtrTopDown.begin();
213 }
214 const_top_down_ptr_iterator top_down_ptr_end() const {
215 return PerPtrTopDown.end();
216 }
217 bool hasTopDownPtrs() const {
218 return !PerPtrTopDown.empty();
219 }
220
221 unsigned top_down_ptr_list_size() const {
222 return std::distance(first: top_down_ptr_begin(), last: top_down_ptr_end());
223 }
224
225 using bottom_up_ptr_iterator = decltype(PerPtrBottomUp)::iterator;
226 using const_bottom_up_ptr_iterator =
227 decltype(PerPtrBottomUp)::const_iterator;
228
229 bottom_up_ptr_iterator bottom_up_ptr_begin() {
230 return PerPtrBottomUp.begin();
231 }
232 bottom_up_ptr_iterator bottom_up_ptr_end() { return PerPtrBottomUp.end(); }
233 const_bottom_up_ptr_iterator bottom_up_ptr_begin() const {
234 return PerPtrBottomUp.begin();
235 }
236 const_bottom_up_ptr_iterator bottom_up_ptr_end() const {
237 return PerPtrBottomUp.end();
238 }
239 bool hasBottomUpPtrs() const {
240 return !PerPtrBottomUp.empty();
241 }
242
243 unsigned bottom_up_ptr_list_size() const {
244 return std::distance(first: bottom_up_ptr_begin(), last: bottom_up_ptr_end());
245 }
246
247 /// Mark this block as being an entry block, which has one path from the
248 /// entry by definition.
249 void SetAsEntry() { TopDownPathCount = 1; }
250
251 /// Mark this block as being an exit block, which has one path to an exit by
252 /// definition.
253 void SetAsExit() { BottomUpPathCount = 1; }
254
255 /// Attempt to find the PtrState object describing the top down state for
256 /// pointer Arg. Return a new initialized PtrState describing the top down
257 /// state for Arg if we do not find one.
258 TopDownPtrState &getPtrTopDownState(const Value *Arg) {
259 return PerPtrTopDown[Arg];
260 }
261
262 /// Attempt to find the PtrState object describing the bottom up state for
263 /// pointer Arg. Return a new initialized PtrState describing the bottom up
264 /// state for Arg if we do not find one.
265 BottomUpPtrState &getPtrBottomUpState(const Value *Arg) {
266 return PerPtrBottomUp[Arg];
267 }
268
269 /// Attempt to find the PtrState object describing the bottom up state for
270 /// pointer Arg.
271 bottom_up_ptr_iterator findPtrBottomUpState(const Value *Arg) {
272 return PerPtrBottomUp.find(Key: Arg);
273 }
274
275 void clearBottomUpPointers() {
276 PerPtrBottomUp.clear();
277 }
278
279 void clearTopDownPointers() {
280 PerPtrTopDown.clear();
281 }
282
283 void InitFromPred(const BBState &Other);
284 void InitFromSucc(const BBState &Other);
285 void MergePred(const BBState &Other);
286 void MergeSucc(const BBState &Other);
287
288 /// Compute the number of possible unique paths from an entry to an exit
289 /// which pass through this block. This is only valid after both the
290 /// top-down and bottom-up traversals are complete.
291 ///
292 /// Returns true if overflow occurred. Returns false if overflow did not
293 /// occur.
294 bool GetAllPathCountWithOverflow(unsigned &PathCount) const {
295 if (TopDownPathCount == OverflowOccurredValue ||
296 BottomUpPathCount == OverflowOccurredValue)
297 return true;
298 unsigned long long Product =
299 (unsigned long long)TopDownPathCount*BottomUpPathCount;
300 // Overflow occurred if any of the upper bits of Product are set or if all
301 // the lower bits of Product are all set.
302 return (Product >> 32) ||
303 ((PathCount = Product) == OverflowOccurredValue);
304 }
305
306 // Specialized CFG utilities.
307 using edge_iterator = SmallVectorImpl<BasicBlock *>::const_iterator;
308
309 edge_iterator pred_begin() const { return Preds.begin(); }
310 edge_iterator pred_end() const { return Preds.end(); }
311 edge_iterator succ_begin() const { return Succs.begin(); }
312 edge_iterator succ_end() const { return Succs.end(); }
313
314 void addSucc(BasicBlock *Succ) { Succs.push_back(Elt: Succ); }
315 void addPred(BasicBlock *Pred) { Preds.push_back(Elt: Pred); }
316
317 bool isExit() const { return Succs.empty(); }
318 };
319
320} // end anonymous namespace
321
322const unsigned BBState::OverflowOccurredValue = 0xffffffff;
323
324namespace llvm {
325
326[[maybe_unused]] raw_ostream &operator<<(raw_ostream &OS, BBState &BBState);
327
328} // end namespace llvm
329
330void BBState::InitFromPred(const BBState &Other) {
331 PerPtrTopDown = Other.PerPtrTopDown;
332 TopDownPathCount = Other.TopDownPathCount;
333}
334
335void BBState::InitFromSucc(const BBState &Other) {
336 PerPtrBottomUp = Other.PerPtrBottomUp;
337 BottomUpPathCount = Other.BottomUpPathCount;
338}
339
340/// The top-down traversal uses this to merge information about predecessors to
341/// form the initial state for a new block.
342void BBState::MergePred(const BBState &Other) {
343 if (TopDownPathCount == OverflowOccurredValue)
344 return;
345
346 // Other.TopDownPathCount can be 0, in which case it is either dead or a
347 // loop backedge. Loop backedges are special.
348 TopDownPathCount += Other.TopDownPathCount;
349
350 // In order to be consistent, we clear the top down pointers when by adding
351 // TopDownPathCount becomes OverflowOccurredValue even though "true" overflow
352 // has not occurred.
353 if (TopDownPathCount == OverflowOccurredValue) {
354 clearTopDownPointers();
355 return;
356 }
357
358 // Check for overflow. If we have overflow, fall back to conservative
359 // behavior.
360 if (TopDownPathCount < Other.TopDownPathCount) {
361 TopDownPathCount = OverflowOccurredValue;
362 clearTopDownPointers();
363 return;
364 }
365
366 // For each entry in the other set, if our set has an entry with the same key,
367 // merge the entries. Otherwise, copy the entry and merge it with an empty
368 // entry.
369 for (auto MI = Other.top_down_ptr_begin(), ME = Other.top_down_ptr_end();
370 MI != ME; ++MI) {
371 auto Pair = PerPtrTopDown.insert(InsertPair: *MI);
372 Pair.first->second.Merge(Other: Pair.second ? TopDownPtrState() : MI->second,
373 /*TopDown=*/true);
374 }
375
376 // For each entry in our set, if the other set doesn't have an entry with the
377 // same key, force it to merge with an empty entry.
378 for (auto MI = top_down_ptr_begin(), ME = top_down_ptr_end(); MI != ME; ++MI)
379 if (Other.PerPtrTopDown.find(Key: MI->first) == Other.PerPtrTopDown.end())
380 MI->second.Merge(Other: TopDownPtrState(), /*TopDown=*/true);
381}
382
383/// The bottom-up traversal uses this to merge information about successors to
384/// form the initial state for a new block.
385void BBState::MergeSucc(const BBState &Other) {
386 if (BottomUpPathCount == OverflowOccurredValue)
387 return;
388
389 // Other.BottomUpPathCount can be 0, in which case it is either dead or a
390 // loop backedge. Loop backedges are special.
391 BottomUpPathCount += Other.BottomUpPathCount;
392
393 // In order to be consistent, we clear the top down pointers when by adding
394 // BottomUpPathCount becomes OverflowOccurredValue even though "true" overflow
395 // has not occurred.
396 if (BottomUpPathCount == OverflowOccurredValue) {
397 clearBottomUpPointers();
398 return;
399 }
400
401 // Check for overflow. If we have overflow, fall back to conservative
402 // behavior.
403 if (BottomUpPathCount < Other.BottomUpPathCount) {
404 BottomUpPathCount = OverflowOccurredValue;
405 clearBottomUpPointers();
406 return;
407 }
408
409 // For each entry in the other set, if our set has an entry with the
410 // same key, merge the entries. Otherwise, copy the entry and merge
411 // it with an empty entry.
412 for (auto MI = Other.bottom_up_ptr_begin(), ME = Other.bottom_up_ptr_end();
413 MI != ME; ++MI) {
414 auto Pair = PerPtrBottomUp.insert(InsertPair: *MI);
415 Pair.first->second.Merge(Other: Pair.second ? BottomUpPtrState() : MI->second,
416 /*TopDown=*/false);
417 }
418
419 // For each entry in our set, if the other set doesn't have an entry
420 // with the same key, force it to merge with an empty entry.
421 for (auto MI = bottom_up_ptr_begin(), ME = bottom_up_ptr_end(); MI != ME;
422 ++MI)
423 if (Other.PerPtrBottomUp.find(Key: MI->first) == Other.PerPtrBottomUp.end())
424 MI->second.Merge(Other: BottomUpPtrState(), /*TopDown=*/false);
425}
426
427raw_ostream &llvm::operator<<(raw_ostream &OS, BBState &BBInfo) {
428 // Dump the pointers we are tracking.
429 OS << " TopDown State:\n";
430 if (!BBInfo.hasTopDownPtrs()) {
431 LLVM_DEBUG(dbgs() << " NONE!\n");
432 } else {
433 for (auto I = BBInfo.top_down_ptr_begin(), E = BBInfo.top_down_ptr_end();
434 I != E; ++I) {
435 const PtrState &P = I->second;
436 OS << " Ptr: " << *I->first
437 << "\n KnownSafe: " << (P.IsKnownSafe()?"true":"false")
438 << "\n ImpreciseRelease: "
439 << (P.IsTrackingImpreciseReleases()?"true":"false") << "\n"
440 << " HasCFGHazards: "
441 << (P.IsCFGHazardAfflicted()?"true":"false") << "\n"
442 << " KnownPositive: "
443 << (P.HasKnownPositiveRefCount()?"true":"false") << "\n"
444 << " Seq: "
445 << P.GetSeq() << "\n";
446 }
447 }
448
449 OS << " BottomUp State:\n";
450 if (!BBInfo.hasBottomUpPtrs()) {
451 LLVM_DEBUG(dbgs() << " NONE!\n");
452 } else {
453 for (auto I = BBInfo.bottom_up_ptr_begin(), E = BBInfo.bottom_up_ptr_end();
454 I != E; ++I) {
455 const PtrState &P = I->second;
456 OS << " Ptr: " << *I->first
457 << "\n KnownSafe: " << (P.IsKnownSafe()?"true":"false")
458 << "\n ImpreciseRelease: "
459 << (P.IsTrackingImpreciseReleases()?"true":"false") << "\n"
460 << " HasCFGHazards: "
461 << (P.IsCFGHazardAfflicted()?"true":"false") << "\n"
462 << " KnownPositive: "
463 << (P.HasKnownPositiveRefCount()?"true":"false") << "\n"
464 << " Seq: "
465 << P.GetSeq() << "\n";
466 }
467 }
468
469 return OS;
470}
471
472namespace {
473
474 /// The main ARC optimization pass.
475class ObjCARCOpt {
476 bool Changed = false;
477 bool CFGChanged = false;
478 ProvenanceAnalysis PA;
479
480 /// A cache of references to runtime entry point constants.
481 ARCRuntimeEntryPoints EP;
482
483 /// A cache of MDKinds that can be passed into other functions to propagate
484 /// MDKind identifiers.
485 ARCMDKindCache MDKindCache;
486
487 BundledRetainClaimRVs *BundledInsts = nullptr;
488
489 /// A flag indicating whether the optimization that removes or moves
490 /// retain/release pairs should be performed.
491 bool DisableRetainReleasePairing = false;
492
493 /// Flags which determine whether each of the interesting runtime functions
494 /// is in fact used in the current function.
495 unsigned UsedInThisFunction;
496
497 DenseMap<BasicBlock *, ColorVector> BlockEHColors;
498
499 /// Cache mapping autorelease instructions to their following
500 /// autoreleasePoolPop in the same basic block (or nullptr if none).
501 DenseMap<Instruction *, Instruction *> FollowingPoolPopCache;
502
503 /// Find the autoreleasePoolPop that will drain the given autorelease
504 /// instruction in the same basic block, skipping nested pools.
505 Instruction *FindFollowingAutoreleasePoolPop(Instruction *AutoreleaseInst);
506
507 bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
508 void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
509 ARCInstKind &Class);
510 void OptimizeIndividualCalls(Function &F);
511
512 /// Optimize an individual call, optionally passing the
513 /// GetArgRCIdentityRoot if it has already been computed.
514 void OptimizeIndividualCallImpl(Function &F, Instruction *Inst,
515 ARCInstKind Class, const Value *Arg);
516
517 /// Try to optimize an AutoreleaseRV with a RetainRV or UnsafeClaimRV. If the
518 /// optimization occurs, returns true to indicate that the caller should
519 /// assume the instructions are dead.
520 bool OptimizeInlinedAutoreleaseRVCall(Function &F, Instruction *Inst,
521 const Value *&Arg, ARCInstKind Class,
522 Instruction *AutoreleaseRV,
523 const Value *&AutoreleaseRVArg);
524
525 void CheckForCFGHazards(const BasicBlock *BB,
526 DenseMap<const BasicBlock *, BBState> &BBStates,
527 BBState &MyStates) const;
528 bool VisitInstructionBottomUp(Instruction *Inst, BasicBlock *BB,
529 BlotMapVector<Value *, RRInfo> &Retains,
530 BBState &MyStates);
531 bool VisitBottomUp(BasicBlock *BB,
532 DenseMap<const BasicBlock *, BBState> &BBStates,
533 BlotMapVector<Value *, RRInfo> &Retains);
534 bool VisitInstructionTopDown(
535 Instruction *Inst, DenseMap<Value *, RRInfo> &Releases, BBState &MyStates,
536 const DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
537 &ReleaseInsertPtToRCIdentityRoots);
538 bool VisitTopDown(
539 BasicBlock *BB, DenseMap<const BasicBlock *, BBState> &BBStates,
540 DenseMap<Value *, RRInfo> &Releases,
541 const DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
542 &ReleaseInsertPtToRCIdentityRoots);
543 bool Visit(Function &F, DenseMap<const BasicBlock *, BBState> &BBStates,
544 BlotMapVector<Value *, RRInfo> &Retains,
545 DenseMap<Value *, RRInfo> &Releases);
546
547 void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
548 BlotMapVector<Value *, RRInfo> &Retains,
549 DenseMap<Value *, RRInfo> &Releases,
550 SmallVectorImpl<Instruction *> &DeadInsts, Module *M);
551
552 bool PairUpRetainsAndReleases(DenseMap<const BasicBlock *, BBState> &BBStates,
553 BlotMapVector<Value *, RRInfo> &Retains,
554 DenseMap<Value *, RRInfo> &Releases, Module *M,
555 Instruction *Retain,
556 SmallVectorImpl<Instruction *> &DeadInsts,
557 RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
558 Value *Arg, bool KnownSafe,
559 bool &AnyPairsCompletelyEliminated);
560
561 bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
562 BlotMapVector<Value *, RRInfo> &Retains,
563 DenseMap<Value *, RRInfo> &Releases, Module *M);
564
565 void OptimizeWeakCalls(Function &F);
566
567 bool OptimizeSequences(Function &F);
568
569 void OptimizeReturns(Function &F);
570
571 void OptimizeAutoreleasePools(Function &F);
572
573 template <typename PredicateT>
574 static void cloneOpBundlesIf(CallBase *CI,
575 SmallVectorImpl<OperandBundleDef> &OpBundles,
576 PredicateT Predicate) {
577 for (unsigned I = 0, E = CI->getNumOperandBundles(); I != E; ++I) {
578 OperandBundleUse B = CI->getOperandBundleAt(Index: I);
579 if (Predicate(B))
580 OpBundles.emplace_back(Args&: B);
581 }
582 }
583
584 void addOpBundleForFunclet(BasicBlock *BB,
585 SmallVectorImpl<OperandBundleDef> &OpBundles) {
586 if (!BlockEHColors.empty()) {
587 const ColorVector &CV = BlockEHColors.find(Val: BB)->second;
588 assert(CV.size() > 0 && "Uncolored block");
589 for (BasicBlock *EHPadBB : CV)
590 if (auto *EHPad =
591 dyn_cast<FuncletPadInst>(Val: EHPadBB->getFirstNonPHIIt())) {
592 OpBundles.emplace_back(Args: "funclet", Args&: EHPad);
593 return;
594 }
595 }
596 }
597
598#ifndef NDEBUG
599 void GatherStatistics(Function &F, bool AfterOptimization = false);
600#endif
601
602 public:
603 void init(Function &F);
604 bool run(Function &F, AAResults &AA);
605 bool hasCFGChanged() const { return CFGChanged; }
606};
607} // end anonymous namespace
608
609/// Find the autoreleasePoolPop that will drain the given autorelease
610/// instruction in the same basic block, skipping over nested pools.
611///
612/// Since objc_autorelease does not change the refcount (it only registers the
613/// object for a deferred release at pool drain), we can move the release to
614/// just before the pool pop instead of converting in place. This avoids the
615/// need to check for uses of the pointer between the autorelease and the pop.
616Instruction *
617ObjCARCOpt::FindFollowingAutoreleasePoolPop(Instruction *AutoreleaseInst) {
618 assert(GetBasicARCInstKind(AutoreleaseInst) == ARCInstKind::Autorelease);
619
620 auto It = FollowingPoolPopCache.find(Val: AutoreleaseInst);
621 if (It != FollowingPoolPopCache.end()) {
622 // The cached value is a raw pointer to a pool pop. The cache is only
623 // consulted during OptimizeIndividualCalls, which runs before
624 // OptimizeAutoreleasePools can erase pool pops.
625 return It->second;
626 }
627
628 BasicBlock *BB = AutoreleaseInst->getParent();
629
630 SmallVector<SmallVector<Instruction *, 2>, 4> AutoreleasesByDepth(1);
631 AutoreleasesByDepth[0].push_back(Elt: AutoreleaseInst);
632
633 unsigned Depth = 0;
634 for (BasicBlock::iterator I = std::next(x: AutoreleaseInst->getIterator()),
635 E = BB->end();
636 I != E; ++I) {
637 ARCInstKind Class = GetBasicARCInstKind(V: &*I);
638
639 if (Class == ARCInstKind::AutoreleasepoolPush) {
640 if (++Depth >= AutoreleasesByDepth.size())
641 AutoreleasesByDepth.emplace_back();
642 else
643 assert(AutoreleasesByDepth[Depth].empty() &&
644 "reused bucket must be empty");
645 } else if (Class == ARCInstKind::AutoreleasepoolPop) {
646 for (Instruction *J : AutoreleasesByDepth[Depth])
647 FollowingPoolPopCache[J] = &*I;
648 AutoreleasesByDepth[Depth].clear();
649 if (Depth == 0)
650 return &*I;
651 --Depth;
652 } else if (Class == ARCInstKind::Autorelease) {
653 AutoreleasesByDepth[Depth].push_back(Elt: &*I);
654 } else if (Class == ARCInstKind::Call || Class == ARCInstKind::CallOrUser) {
655 // A call can push or pop an autorelease pool, which dynamically
656 // changes the pool stack. We cannot rely on the syntactic scan anymore.
657 // Break out and cache the nullptr result for all accumulated
658 // autoreleases.
659 break;
660 }
661 }
662
663 for (const auto &Autoreleases : AutoreleasesByDepth)
664 for (Instruction *I : Autoreleases)
665 FollowingPoolPopCache[I] = nullptr;
666 return nullptr;
667}
668
669/// Turn objc_retainAutoreleasedReturnValue into objc_retain if the operand is
670/// not a return value.
671bool
672ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
673 // Check for the argument being from an immediately preceding call or invoke.
674 const Value *Arg = GetArgRCIdentityRoot(Inst: RetainRV);
675 if (const Instruction *Call = dyn_cast<CallBase>(Val: Arg)) {
676 if (Call->getParent() == RetainRV->getParent()) {
677 BasicBlock::const_iterator I(Call);
678 do
679 ++I;
680 while (IsNoopInstruction(I: &*I));
681 if (&*I == RetainRV)
682 return false;
683 } else if (const InvokeInst *II = dyn_cast<InvokeInst>(Val: Call)) {
684 BasicBlock *RetainRVParent = RetainRV->getParent();
685 if (II->getNormalDest() == RetainRVParent) {
686 BasicBlock::const_iterator I = RetainRVParent->begin();
687 while (IsNoopInstruction(I: &*I))
688 ++I;
689 if (&*I == RetainRV)
690 return false;
691 }
692 }
693 }
694
695 assert(!BundledInsts->contains(RetainRV) &&
696 "a bundled retainRV's argument should be a call");
697
698 // Turn it to a plain objc_retain.
699 Changed = true;
700 ++NumPeeps;
701
702 LLVM_DEBUG(dbgs() << "Transforming objc_retainAutoreleasedReturnValue => "
703 "objc_retain since the operand is not a return value.\n"
704 "Old = "
705 << *RetainRV << "\n");
706
707 Function *NewDecl = EP.get(kind: ARCRuntimeEntryPointKind::Retain);
708 cast<CallInst>(Val: RetainRV)->setCalledFunction(NewDecl);
709
710 LLVM_DEBUG(dbgs() << "New = " << *RetainRV << "\n");
711
712 return false;
713}
714
715bool ObjCARCOpt::OptimizeInlinedAutoreleaseRVCall(
716 Function &F, Instruction *Inst, const Value *&Arg, ARCInstKind Class,
717 Instruction *AutoreleaseRV, const Value *&AutoreleaseRVArg) {
718 if (BundledInsts->contains(I: Inst))
719 return false;
720
721 // Must be in the same basic block.
722 assert(Inst->getParent() == AutoreleaseRV->getParent());
723
724 // Must operate on the same root.
725 Arg = GetArgRCIdentityRoot(Inst);
726 AutoreleaseRVArg = GetArgRCIdentityRoot(Inst: AutoreleaseRV);
727 if (Arg != AutoreleaseRVArg) {
728 // If there isn't an exact match, check if we have equivalent PHIs.
729 const PHINode *PN = dyn_cast<PHINode>(Val: Arg);
730 if (!PN)
731 return false;
732
733 SmallVector<const Value *, 4> ArgUsers;
734 getEquivalentPHIs(PN: *PN, PHIList&: ArgUsers);
735 if (!llvm::is_contained(Range&: ArgUsers, Element: AutoreleaseRVArg))
736 return false;
737 }
738
739 // Okay, this is a match. Merge them.
740 ++NumPeeps;
741 LLVM_DEBUG(dbgs() << "Found inlined objc_autoreleaseReturnValue '"
742 << *AutoreleaseRV << "' paired with '" << *Inst << "'\n");
743
744 // Delete the RV pair, starting with the AutoreleaseRV.
745 AutoreleaseRV->replaceAllUsesWith(
746 V: cast<CallInst>(Val: AutoreleaseRV)->getArgOperand(i: 0));
747 Changed = true;
748 EraseInstruction(CI: AutoreleaseRV);
749 if (Class == ARCInstKind::RetainRV) {
750 // AutoreleaseRV and RetainRV cancel out. Delete the RetainRV.
751 Inst->replaceAllUsesWith(V: cast<CallInst>(Val: Inst)->getArgOperand(i: 0));
752 EraseInstruction(CI: Inst);
753 return true;
754 }
755
756 // UnsafeClaimRV is a frontend peephole for RetainRV + Release. Since the
757 // AutoreleaseRV and RetainRV cancel out, replace UnsafeClaimRV with Release.
758 assert(Class == ARCInstKind::UnsafeClaimRV);
759 Value *CallArg = cast<CallInst>(Val: Inst)->getArgOperand(i: 0);
760 CallInst *Release =
761 CallInst::Create(Func: EP.get(kind: ARCRuntimeEntryPointKind::Release), Args: CallArg, NameStr: "",
762 InsertBefore: Inst->getIterator());
763 assert(IsAlwaysTail(ARCInstKind::UnsafeClaimRV) &&
764 "Expected UnsafeClaimRV to be safe to tail call");
765 Release->setTailCall();
766 Inst->replaceAllUsesWith(V: CallArg);
767 EraseInstruction(CI: Inst);
768
769 // Run the normal optimizations on Release.
770 OptimizeIndividualCallImpl(F, Inst: Release, Class: ARCInstKind::Release, Arg);
771 return true;
772}
773
774/// Turn objc_autoreleaseReturnValue into objc_autorelease if the result is not
775/// used as a return value.
776void ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F,
777 Instruction *AutoreleaseRV,
778 ARCInstKind &Class) {
779 // Check for a return of the pointer value.
780 const Value *Ptr = GetArgRCIdentityRoot(Inst: AutoreleaseRV);
781
782 // If the argument is ConstantPointerNull or UndefValue, its other users
783 // aren't actually interesting to look at.
784 if (isa<ConstantData>(Val: Ptr))
785 return;
786
787 SmallVector<const Value *, 2> Users;
788 Users.push_back(Elt: Ptr);
789
790 // Add PHIs that are equivalent to Ptr to Users.
791 if (const PHINode *PN = dyn_cast<PHINode>(Val: Ptr))
792 getEquivalentPHIs(PN: *PN, PHIList&: Users);
793
794 do {
795 Ptr = Users.pop_back_val();
796 for (const User *U : Ptr->users()) {
797 if (isa<ReturnInst>(Val: U) || GetBasicARCInstKind(V: U) == ARCInstKind::RetainRV)
798 return;
799 if (isa<BitCastInst>(Val: U))
800 Users.push_back(Elt: U);
801 }
802 } while (!Users.empty());
803
804 Changed = true;
805 ++NumPeeps;
806
807 LLVM_DEBUG(
808 dbgs() << "Transforming objc_autoreleaseReturnValue => "
809 "objc_autorelease since its operand is not used as a return "
810 "value.\n"
811 "Old = "
812 << *AutoreleaseRV << "\n");
813
814 CallInst *AutoreleaseRVCI = cast<CallInst>(Val: AutoreleaseRV);
815 Function *NewDecl = EP.get(kind: ARCRuntimeEntryPointKind::Autorelease);
816 AutoreleaseRVCI->setCalledFunction(NewDecl);
817 AutoreleaseRVCI->setTailCall(false); // Never tail call objc_autorelease.
818 Class = ARCInstKind::Autorelease;
819
820 LLVM_DEBUG(dbgs() << "New: " << *AutoreleaseRV << "\n");
821}
822
823/// Visit each call, one at a time, and make simplifications without doing any
824/// additional analysis.
825void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
826 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeIndividualCalls ==\n");
827 // Reset all the flags in preparation for recomputing them.
828 UsedInThisFunction = 0;
829 // Clear the autorelease pool pop cache for this function
830 FollowingPoolPopCache.clear();
831
832 // Store any delayed AutoreleaseRV intrinsics, so they can be easily paired
833 // with RetainRV and UnsafeClaimRV.
834 Instruction *DelayedAutoreleaseRV = nullptr;
835 const Value *DelayedAutoreleaseRVArg = nullptr;
836 auto setDelayedAutoreleaseRV = [&](Instruction *AutoreleaseRV) {
837 assert(!DelayedAutoreleaseRV || !AutoreleaseRV);
838 DelayedAutoreleaseRV = AutoreleaseRV;
839 DelayedAutoreleaseRVArg = nullptr;
840 };
841 auto optimizeDelayedAutoreleaseRV = [&]() {
842 if (!DelayedAutoreleaseRV)
843 return;
844 OptimizeIndividualCallImpl(F, Inst: DelayedAutoreleaseRV,
845 Class: ARCInstKind::AutoreleaseRV,
846 Arg: DelayedAutoreleaseRVArg);
847 setDelayedAutoreleaseRV(nullptr);
848 };
849 auto shouldDelayAutoreleaseRV = [&](Instruction *NonARCInst) {
850 // Nothing to delay, but we may as well skip the logic below.
851 if (!DelayedAutoreleaseRV)
852 return true;
853
854 // If we hit the end of the basic block we're not going to find an RV-pair.
855 // Stop delaying.
856 if (NonARCInst->isTerminator())
857 return false;
858
859 // Given the frontend rules for emitting AutoreleaseRV, RetainRV, and
860 // UnsafeClaimRV, it's probably safe to skip over even opaque function calls
861 // here since OptimizeInlinedAutoreleaseRVCall will confirm that they
862 // have the same RCIdentityRoot. However, what really matters is
863 // skipping instructions or intrinsics that the inliner could leave behind;
864 // be conservative for now and don't skip over opaque calls, which could
865 // potentially include other ARC calls.
866 auto *CB = dyn_cast<CallBase>(Val: NonARCInst);
867 if (!CB)
868 return true;
869 return CB->getIntrinsicID() != Intrinsic::not_intrinsic;
870 };
871
872 // Visit all objc_* calls in F.
873 for (inst_iterator I = inst_begin(F: &F), E = inst_end(F: &F); I != E; ) {
874 Instruction *Inst = &*I++;
875
876 if (auto *CI = dyn_cast<CallInst>(Val: Inst))
877 if (objcarc::hasAttachedCallOpBundle(CB: CI)) {
878 BundledInsts->insertRVCall(InsertPt: I->getIterator(), AnnotatedCall: CI);
879 Changed = true;
880 }
881
882 ARCInstKind Class = GetBasicARCInstKind(V: Inst);
883
884 // Skip this loop if this instruction isn't itself an ARC intrinsic.
885 const Value *Arg = nullptr;
886 switch (Class) {
887 default:
888 optimizeDelayedAutoreleaseRV();
889 break;
890 case ARCInstKind::CallOrUser:
891 case ARCInstKind::User:
892 case ARCInstKind::None:
893 // This is a non-ARC instruction. If we're delaying an AutoreleaseRV,
894 // check if it's safe to skip over it; if not, optimize the AutoreleaseRV
895 // now.
896 if (!shouldDelayAutoreleaseRV(Inst))
897 optimizeDelayedAutoreleaseRV();
898 continue;
899 case ARCInstKind::AutoreleaseRV:
900 optimizeDelayedAutoreleaseRV();
901 setDelayedAutoreleaseRV(Inst);
902 continue;
903 case ARCInstKind::RetainRV:
904 case ARCInstKind::UnsafeClaimRV:
905 if (DelayedAutoreleaseRV) {
906 // We have a potential RV pair. Check if they cancel out.
907 if (OptimizeInlinedAutoreleaseRVCall(F, Inst, Arg, Class,
908 AutoreleaseRV: DelayedAutoreleaseRV,
909 AutoreleaseRVArg&: DelayedAutoreleaseRVArg)) {
910 setDelayedAutoreleaseRV(nullptr);
911 continue;
912 }
913 optimizeDelayedAutoreleaseRV();
914 }
915 break;
916 }
917
918 OptimizeIndividualCallImpl(F, Inst, Class, Arg);
919 }
920
921 // Catch the final delayed AutoreleaseRV.
922 optimizeDelayedAutoreleaseRV();
923}
924
925/// This function returns true if the value is inert. An ObjC ARC runtime call
926/// taking an inert operand can be safely deleted.
927static bool isInertARCValue(Value *V, SmallPtrSet<Value *, 1> &VisitedPhis) {
928 V = V->stripPointerCasts();
929
930 if (IsNullOrUndef(V))
931 return true;
932
933 // See if this is a global attribute annotated with an 'objc_arc_inert'.
934 if (auto *GV = dyn_cast<GlobalVariable>(Val: V))
935 if (GV->hasAttribute(Kind: "objc_arc_inert"))
936 return true;
937
938 if (auto PN = dyn_cast<PHINode>(Val: V)) {
939 // Ignore this phi if it has already been discovered.
940 if (!VisitedPhis.insert(Ptr: PN).second)
941 return true;
942 // Look through phis's operands.
943 for (Value *Opnd : PN->incoming_values())
944 if (!isInertARCValue(V: Opnd, VisitedPhis))
945 return false;
946 return true;
947 }
948
949 return false;
950}
951
952void ObjCARCOpt::OptimizeIndividualCallImpl(Function &F, Instruction *Inst,
953 ARCInstKind Class,
954 const Value *Arg) {
955 LLVM_DEBUG(dbgs() << "Visiting: Class: " << Class << "; " << *Inst << "\n");
956
957 // We can delete this call if it takes an inert value.
958 SmallPtrSet<Value *, 1> VisitedPhis;
959
960 if (BundledInsts->contains(I: Inst)) {
961 UsedInThisFunction |= 1 << unsigned(Class);
962 return;
963 }
964
965 if (IsNoopOnGlobal(Class))
966 if (isInertARCValue(V: Inst->getOperand(i: 0), VisitedPhis)) {
967 if (!Inst->getType()->isVoidTy())
968 Inst->replaceAllUsesWith(V: Inst->getOperand(i: 0));
969 Inst->eraseFromParent();
970 Changed = true;
971 return;
972 }
973
974 switch (Class) {
975 default:
976 break;
977
978 // Delete no-op casts. These function calls have special semantics, but
979 // the semantics are entirely implemented via lowering in the front-end,
980 // so by the time they reach the optimizer, they are just no-op calls
981 // which return their argument.
982 //
983 // There are gray areas here, as the ability to cast reference-counted
984 // pointers to raw void* and back allows code to break ARC assumptions,
985 // however these are currently considered to be unimportant.
986 case ARCInstKind::NoopCast:
987 Changed = true;
988 ++NumNoops;
989 LLVM_DEBUG(dbgs() << "Erasing no-op cast: " << *Inst << "\n");
990 EraseInstruction(CI: Inst);
991 return;
992
993 // If the pointer-to-weak-pointer is null, it's undefined behavior.
994 case ARCInstKind::StoreWeak:
995 case ARCInstKind::LoadWeak:
996 case ARCInstKind::LoadWeakRetained:
997 case ARCInstKind::InitWeak:
998 case ARCInstKind::DestroyWeak: {
999 CallInst *CI = cast<CallInst>(Val: Inst);
1000 if (IsNullOrUndef(V: CI->getArgOperand(i: 0))) {
1001 Changed = true;
1002 new StoreInst(ConstantInt::getTrue(Context&: CI->getContext()),
1003 PoisonValue::get(T: PointerType::getUnqual(C&: CI->getContext())),
1004 CI->getIterator());
1005 Value *NewValue = PoisonValue::get(T: CI->getType());
1006 LLVM_DEBUG(
1007 dbgs() << "A null pointer-to-weak-pointer is undefined behavior."
1008 "\nOld = "
1009 << *CI << "\nNew = " << *NewValue << "\n");
1010 CI->replaceAllUsesWith(V: NewValue);
1011 CI->eraseFromParent();
1012 return;
1013 }
1014 break;
1015 }
1016 case ARCInstKind::CopyWeak:
1017 case ARCInstKind::MoveWeak: {
1018 CallInst *CI = cast<CallInst>(Val: Inst);
1019 if (IsNullOrUndef(V: CI->getArgOperand(i: 0)) ||
1020 IsNullOrUndef(V: CI->getArgOperand(i: 1))) {
1021 Changed = true;
1022 new StoreInst(ConstantInt::getTrue(Context&: CI->getContext()),
1023 PoisonValue::get(T: PointerType::getUnqual(C&: CI->getContext())),
1024 CI->getIterator());
1025
1026 Value *NewValue = PoisonValue::get(T: CI->getType());
1027 LLVM_DEBUG(
1028 dbgs() << "A null pointer-to-weak-pointer is undefined behavior."
1029 "\nOld = "
1030 << *CI << "\nNew = " << *NewValue << "\n");
1031
1032 CI->replaceAllUsesWith(V: NewValue);
1033 CI->eraseFromParent();
1034 return;
1035 }
1036 break;
1037 }
1038 case ARCInstKind::RetainRV:
1039 if (OptimizeRetainRVCall(F, RetainRV: Inst))
1040 return;
1041 break;
1042 case ARCInstKind::AutoreleaseRV:
1043 OptimizeAutoreleaseRVCall(F, AutoreleaseRV: Inst, Class);
1044 break;
1045 }
1046
1047 // objc_autorelease(x) -> objc_release(x) if x is otherwise unused.
1048 if (IsAutorelease(Class) && Inst->use_empty()) {
1049 CallInst *Call = cast<CallInst>(Val: Inst);
1050 const Value *Arg = Call->getArgOperand(i: 0);
1051 Arg = FindSingleUseIdentifiedObject(Arg);
1052 if (Arg) {
1053 Changed = true;
1054 ++NumAutoreleases;
1055
1056 LLVMContext &C = Inst->getContext();
1057 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Release);
1058 CallInst *NewCall = CallInst::Create(Func: Decl, Args: Call->getArgOperand(i: 0), NameStr: "",
1059 InsertBefore: Call->getIterator());
1060 NewCall->setMetadata(KindID: MDKindCache.get(ID: ARCMDKindID::ImpreciseRelease),
1061 Node: MDNode::get(Context&: C, MDs: {}));
1062
1063 LLVM_DEBUG(
1064 dbgs() << "Replacing objc_autorelease(x) with objc_release(x)\n");
1065
1066 FollowingPoolPopCache.erase(Val: Call);
1067 EraseInstruction(CI: Call);
1068 Inst = NewCall;
1069 Class = ARCInstKind::Release;
1070 }
1071 }
1072
1073 // objc_autorelease(x) -> objc_release(x) moved to just before the
1074 // autoreleasePoolPop. Since autorelease only registers a deferred release
1075 // at pool drain time without changing the refcount, placing the release at
1076 // the drain point is semantically equivalent and avoids use-after-free
1077 // concerns with in-place conversion.
1078 if (Class == ARCInstKind::Autorelease) {
1079 if (Instruction *PoolPop = FindFollowingAutoreleasePoolPop(AutoreleaseInst: Inst)) {
1080 CallInst *Call = cast<CallInst>(Val: Inst);
1081 Changed = true;
1082 ++NumAutoreleases;
1083
1084 LLVMContext &C = Inst->getContext();
1085 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Release);
1086 CallInst *NewCall = CallInst::Create(Func: Decl, Args: Call->getArgOperand(i: 0), NameStr: "",
1087 InsertBefore: PoolPop->getIterator());
1088 NewCall->setMetadata(KindID: MDKindCache.get(ID: ARCMDKindID::ImpreciseRelease),
1089 Node: MDNode::get(Context&: C, MDs: {}));
1090
1091 LLVM_DEBUG(dbgs() << "Converting autorelease to release before pool pop."
1092 "\nOld: "
1093 << *Call << "\nNew: " << *NewCall << "\n");
1094
1095 assert(Call->getType() == Call->getArgOperand(0)->getType() &&
1096 "objc_autorelease result and argument types must match");
1097 Call->replaceAllUsesWith(V: Call->getArgOperand(i: 0));
1098 // Inserting each release before the pop in visitation order changes the
1099 // drain order from LIFO to FIFO. This is acceptable because the pass
1100 // already does not preserve pool drain order elsewhere (e.g., the
1101 // use_empty() conversion above releases immediately in place).
1102 FollowingPoolPopCache.erase(Val: Call);
1103 EraseInstruction(CI: Call);
1104 Inst = NewCall;
1105 Class = ARCInstKind::Release;
1106 }
1107 }
1108
1109 // For functions which can never be passed stack arguments, add
1110 // a tail keyword.
1111 if (IsAlwaysTail(Class) && !cast<CallInst>(Val: Inst)->isNoTailCall()) {
1112 Changed = true;
1113 LLVM_DEBUG(
1114 dbgs() << "Adding tail keyword to function since it can never be "
1115 "passed stack args: "
1116 << *Inst << "\n");
1117 cast<CallInst>(Val: Inst)->setTailCall();
1118 }
1119
1120 // Ensure that functions that can never have a "tail" keyword due to the
1121 // semantics of ARC truly do not do so.
1122 if (IsNeverTail(Class)) {
1123 Changed = true;
1124 LLVM_DEBUG(dbgs() << "Removing tail keyword from function: " << *Inst
1125 << "\n");
1126 cast<CallInst>(Val: Inst)->setTailCall(false);
1127 }
1128
1129 // Set nounwind as needed.
1130 if (IsNoThrow(Class)) {
1131 Changed = true;
1132 LLVM_DEBUG(dbgs() << "Found no throw class. Setting nounwind on: " << *Inst
1133 << "\n");
1134 cast<CallInst>(Val: Inst)->setDoesNotThrow();
1135 }
1136
1137 // Note: This catches instructions unrelated to ARC.
1138 if (!IsNoopOnNull(Class)) {
1139 UsedInThisFunction |= 1 << unsigned(Class);
1140 return;
1141 }
1142
1143 // If we haven't already looked up the root, look it up now.
1144 if (!Arg)
1145 Arg = GetArgRCIdentityRoot(Inst);
1146
1147 // ARC calls with null are no-ops. Delete them.
1148 if (IsNullOrUndef(V: Arg)) {
1149 Changed = true;
1150 ++NumNoops;
1151 LLVM_DEBUG(dbgs() << "ARC calls with null are no-ops. Erasing: " << *Inst
1152 << "\n");
1153 EraseInstruction(CI: Inst);
1154 return;
1155 }
1156
1157 // Keep track of which of retain, release, autorelease, and retain_block
1158 // are actually present in this function.
1159 UsedInThisFunction |= 1 << unsigned(Class);
1160
1161 // If Arg is a PHI, and one or more incoming values to the
1162 // PHI are null, and the call is control-equivalent to the PHI, and there
1163 // are no relevant side effects between the PHI and the call, and the call
1164 // is not a release that doesn't have the clang.imprecise_release tag, the
1165 // call could be pushed up to just those paths with non-null incoming
1166 // values. For now, don't bother splitting critical edges for this.
1167 if (Class == ARCInstKind::Release &&
1168 !Inst->getMetadata(KindID: MDKindCache.get(ID: ARCMDKindID::ImpreciseRelease)))
1169 return;
1170
1171 SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
1172 Worklist.push_back(Elt: std::make_pair(x&: Inst, y&: Arg));
1173 do {
1174 std::pair<Instruction *, const Value *> Pair = Worklist.pop_back_val();
1175 Inst = Pair.first;
1176 Arg = Pair.second;
1177
1178 const PHINode *PN = dyn_cast<PHINode>(Val: Arg);
1179 if (!PN)
1180 continue;
1181
1182 // Determine if the PHI has any null operands, or any incoming
1183 // critical edges.
1184 bool HasNull = false;
1185 bool HasCriticalEdges = false;
1186 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
1187 Value *Incoming = GetRCIdentityRoot(V: PN->getIncomingValue(i));
1188 if (IsNullOrUndef(V: Incoming))
1189 HasNull = true;
1190 else if (PN->getIncomingBlock(i)->getTerminator()->getNumSuccessors() !=
1191 1) {
1192 HasCriticalEdges = true;
1193 break;
1194 }
1195 }
1196 // If we have null operands and no critical edges, optimize.
1197 if (HasCriticalEdges)
1198 continue;
1199 if (!HasNull)
1200 continue;
1201
1202 Instruction *DepInst = nullptr;
1203
1204 // Check that there is nothing that cares about the reference
1205 // count between the call and the phi.
1206 switch (Class) {
1207 case ARCInstKind::Retain:
1208 case ARCInstKind::RetainBlock:
1209 // These can always be moved up.
1210 break;
1211 case ARCInstKind::Release:
1212 // These can't be moved across things that care about the retain
1213 // count.
1214 DepInst = findSingleDependency(Flavor: NeedsPositiveRetainCount, Arg,
1215 StartBB: Inst->getParent(), StartInst: Inst, PA);
1216 break;
1217 case ARCInstKind::Autorelease:
1218 // These can't be moved across autorelease pool scope boundaries.
1219 DepInst = findSingleDependency(Flavor: AutoreleasePoolBoundary, Arg,
1220 StartBB: Inst->getParent(), StartInst: Inst, PA);
1221 break;
1222 case ARCInstKind::UnsafeClaimRV:
1223 case ARCInstKind::RetainRV:
1224 case ARCInstKind::AutoreleaseRV:
1225 // Don't move these; the RV optimization depends on the autoreleaseRV
1226 // being tail called, and the retainRV being immediately after a call
1227 // (which might still happen if we get lucky with codegen layout, but
1228 // it's not worth taking the chance).
1229 continue;
1230 default:
1231 llvm_unreachable("Invalid dependence flavor");
1232 }
1233
1234 if (DepInst != PN)
1235 continue;
1236
1237 Changed = true;
1238 ++NumPartialNoops;
1239 // Clone the call into each predecessor that has a non-null value.
1240 CallInst *CInst = cast<CallInst>(Val: Inst);
1241 Type *ParamTy = CInst->getArgOperand(i: 0)->getType();
1242 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
1243 Value *Incoming = GetRCIdentityRoot(V: PN->getIncomingValue(i));
1244 if (IsNullOrUndef(V: Incoming))
1245 continue;
1246 Value *Op = PN->getIncomingValue(i);
1247 BasicBlock::iterator InsertPos =
1248 PN->getIncomingBlock(i)->back().getIterator();
1249 SmallVector<OperandBundleDef, 1> OpBundles;
1250 cloneOpBundlesIf(CI: CInst, OpBundles, Predicate: [](const OperandBundleUse &B) {
1251 return B.getTagID() != LLVMContext::OB_funclet;
1252 });
1253 addOpBundleForFunclet(BB: InsertPos->getParent(), OpBundles);
1254 CallInst *Clone = CallInst::Create(CI: CInst, Bundles: OpBundles);
1255 if (Op->getType() != ParamTy)
1256 Op = new BitCastInst(Op, ParamTy, "", InsertPos);
1257 Clone->setArgOperand(i: 0, v: Op);
1258 Clone->insertBefore(BB&: *InsertPos->getParent(), InsertPos);
1259
1260 LLVM_DEBUG(dbgs() << "Cloning " << *CInst << "\n"
1261 "And inserting clone at "
1262 << *InsertPos << "\n");
1263 Worklist.push_back(Elt: std::make_pair(x&: Clone, y&: Incoming));
1264 }
1265 // Erase the original call.
1266 LLVM_DEBUG(dbgs() << "Erasing: " << *CInst << "\n");
1267 FollowingPoolPopCache.erase(Val: CInst);
1268 EraseInstruction(CI: CInst);
1269 } while (!Worklist.empty());
1270}
1271
1272/// If we have a top down pointer in the S_Use state, make sure that there are
1273/// no CFG hazards by checking the states of various bottom up pointers.
1274static void CheckForUseCFGHazard(const Sequence SuccSSeq,
1275 const bool SuccSRRIKnownSafe,
1276 TopDownPtrState &S,
1277 bool &SomeSuccHasSame,
1278 bool &AllSuccsHaveSame,
1279 bool &NotAllSeqEqualButKnownSafe,
1280 bool &ShouldContinue) {
1281 switch (SuccSSeq) {
1282 case S_CanRelease: {
1283 if (!S.IsKnownSafe() && !SuccSRRIKnownSafe) {
1284 S.ClearSequenceProgress();
1285 break;
1286 }
1287 S.SetCFGHazardAfflicted(true);
1288 ShouldContinue = true;
1289 break;
1290 }
1291 case S_Use:
1292 SomeSuccHasSame = true;
1293 break;
1294 case S_Stop:
1295 case S_MovableRelease:
1296 if (!S.IsKnownSafe() && !SuccSRRIKnownSafe)
1297 AllSuccsHaveSame = false;
1298 else
1299 NotAllSeqEqualButKnownSafe = true;
1300 break;
1301 case S_Retain:
1302 llvm_unreachable("bottom-up pointer in retain state!");
1303 case S_None:
1304 llvm_unreachable("This should have been handled earlier.");
1305 }
1306}
1307
1308/// If we have a Top Down pointer in the S_CanRelease state, make sure that
1309/// there are no CFG hazards by checking the states of various bottom up
1310/// pointers.
1311static void CheckForCanReleaseCFGHazard(const Sequence SuccSSeq,
1312 const bool SuccSRRIKnownSafe,
1313 TopDownPtrState &S,
1314 bool &SomeSuccHasSame,
1315 bool &AllSuccsHaveSame,
1316 bool &NotAllSeqEqualButKnownSafe) {
1317 switch (SuccSSeq) {
1318 case S_CanRelease:
1319 SomeSuccHasSame = true;
1320 break;
1321 case S_Stop:
1322 case S_MovableRelease:
1323 case S_Use:
1324 if (!S.IsKnownSafe() && !SuccSRRIKnownSafe)
1325 AllSuccsHaveSame = false;
1326 else
1327 NotAllSeqEqualButKnownSafe = true;
1328 break;
1329 case S_Retain:
1330 llvm_unreachable("bottom-up pointer in retain state!");
1331 case S_None:
1332 llvm_unreachable("This should have been handled earlier.");
1333 }
1334}
1335
1336/// Check for critical edges, loop boundaries, irreducible control flow, or
1337/// other CFG structures where moving code across the edge would result in it
1338/// being executed more.
1339void
1340ObjCARCOpt::CheckForCFGHazards(const BasicBlock *BB,
1341 DenseMap<const BasicBlock *, BBState> &BBStates,
1342 BBState &MyStates) const {
1343 // If any top-down local-use or possible-dec has a succ which is earlier in
1344 // the sequence, forget it.
1345 for (auto I = MyStates.top_down_ptr_begin(), E = MyStates.top_down_ptr_end();
1346 I != E; ++I) {
1347 TopDownPtrState &S = I->second;
1348 const Sequence Seq = I->second.GetSeq();
1349
1350 // We only care about S_Retain, S_CanRelease, and S_Use.
1351 if (Seq == S_None)
1352 continue;
1353
1354 // Make sure that if extra top down states are added in the future that this
1355 // code is updated to handle it.
1356 assert((Seq == S_Retain || Seq == S_CanRelease || Seq == S_Use) &&
1357 "Unknown top down sequence state.");
1358
1359 const Value *Arg = I->first;
1360 bool SomeSuccHasSame = false;
1361 bool AllSuccsHaveSame = true;
1362 bool NotAllSeqEqualButKnownSafe = false;
1363
1364 for (const BasicBlock *Succ : successors(BB)) {
1365 // If VisitBottomUp has pointer information for this successor, take
1366 // what we know about it.
1367 const auto BBI = BBStates.find(Val: Succ);
1368 assert(BBI != BBStates.end());
1369 const BottomUpPtrState &SuccS = BBI->second.getPtrBottomUpState(Arg);
1370 const Sequence SuccSSeq = SuccS.GetSeq();
1371
1372 // If bottom up, the pointer is in an S_None state, clear the sequence
1373 // progress since the sequence in the bottom up state finished
1374 // suggesting a mismatch in between retains/releases. This is true for
1375 // all three cases that we are handling here: S_Retain, S_Use, and
1376 // S_CanRelease.
1377 if (SuccSSeq == S_None) {
1378 S.ClearSequenceProgress();
1379 continue;
1380 }
1381
1382 // If we have S_Use or S_CanRelease, perform our check for cfg hazard
1383 // checks.
1384 const bool SuccSRRIKnownSafe = SuccS.IsKnownSafe();
1385
1386 // *NOTE* We do not use Seq from above here since we are allowing for
1387 // S.GetSeq() to change while we are visiting basic blocks.
1388 switch(S.GetSeq()) {
1389 case S_Use: {
1390 bool ShouldContinue = false;
1391 CheckForUseCFGHazard(SuccSSeq, SuccSRRIKnownSafe, S, SomeSuccHasSame,
1392 AllSuccsHaveSame, NotAllSeqEqualButKnownSafe,
1393 ShouldContinue);
1394 if (ShouldContinue)
1395 continue;
1396 break;
1397 }
1398 case S_CanRelease:
1399 CheckForCanReleaseCFGHazard(SuccSSeq, SuccSRRIKnownSafe, S,
1400 SomeSuccHasSame, AllSuccsHaveSame,
1401 NotAllSeqEqualButKnownSafe);
1402 break;
1403 case S_Retain:
1404 case S_None:
1405 case S_Stop:
1406 case S_MovableRelease:
1407 break;
1408 }
1409 }
1410
1411 // If the state at the other end of any of the successor edges
1412 // matches the current state, require all edges to match. This
1413 // guards against loops in the middle of a sequence.
1414 if (SomeSuccHasSame && !AllSuccsHaveSame) {
1415 S.ClearSequenceProgress();
1416 } else if (NotAllSeqEqualButKnownSafe) {
1417 // If we would have cleared the state foregoing the fact that we are known
1418 // safe, stop code motion. This is because whether or not it is safe to
1419 // remove RR pairs via KnownSafe is an orthogonal concept to whether we
1420 // are allowed to perform code motion.
1421 S.SetCFGHazardAfflicted(true);
1422 }
1423 }
1424}
1425
1426bool ObjCARCOpt::VisitInstructionBottomUp(
1427 Instruction *Inst, BasicBlock *BB, BlotMapVector<Value *, RRInfo> &Retains,
1428 BBState &MyStates) {
1429 bool NestingDetected = false;
1430 ARCInstKind Class = GetARCInstKind(V: Inst);
1431 const Value *Arg = nullptr;
1432
1433 LLVM_DEBUG(dbgs() << " Class: " << Class << "\n");
1434
1435 switch (Class) {
1436 case ARCInstKind::Release: {
1437 Arg = GetArgRCIdentityRoot(Inst);
1438
1439 BottomUpPtrState &S = MyStates.getPtrBottomUpState(Arg);
1440 NestingDetected |= S.InitBottomUp(Cache&: MDKindCache, I: Inst);
1441 break;
1442 }
1443 case ARCInstKind::RetainBlock:
1444 // In OptimizeIndividualCalls, we have strength reduced all optimizable
1445 // objc_retainBlocks to objc_retains. Thus at this point any
1446 // objc_retainBlocks that we see are not optimizable.
1447 break;
1448 case ARCInstKind::Retain:
1449 case ARCInstKind::RetainRV: {
1450 Arg = GetArgRCIdentityRoot(Inst);
1451 BottomUpPtrState &S = MyStates.getPtrBottomUpState(Arg);
1452 if (S.MatchWithRetain()) {
1453 // Don't do retain+release tracking for ARCInstKind::RetainRV, because
1454 // it's better to let it remain as the first instruction after a call.
1455 if (Class != ARCInstKind::RetainRV) {
1456 LLVM_DEBUG(dbgs() << " Matching with: " << *Inst << "\n");
1457 Retains[Inst] = S.GetRRInfo();
1458 }
1459 S.ClearSequenceProgress();
1460 }
1461 // A retain moving bottom up can be a use.
1462 break;
1463 }
1464 case ARCInstKind::AutoreleasepoolPop:
1465 // Conservatively, clear MyStates for all known pointers.
1466 MyStates.clearBottomUpPointers();
1467 return NestingDetected;
1468 case ARCInstKind::AutoreleasepoolPush:
1469 case ARCInstKind::None:
1470 // These are irrelevant.
1471 return NestingDetected;
1472 default:
1473 break;
1474 }
1475
1476 // Consider any other possible effects of this instruction on each
1477 // pointer being tracked.
1478 for (auto MI = MyStates.bottom_up_ptr_begin(),
1479 ME = MyStates.bottom_up_ptr_end();
1480 MI != ME; ++MI) {
1481 const Value *Ptr = MI->first;
1482 if (Ptr == Arg)
1483 continue; // Handled above.
1484 BottomUpPtrState &S = MI->second;
1485
1486 if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class))
1487 continue;
1488
1489 S.HandlePotentialUse(BB, Inst, Ptr, PA, Class);
1490 }
1491
1492 return NestingDetected;
1493}
1494
1495bool ObjCARCOpt::VisitBottomUp(BasicBlock *BB,
1496 DenseMap<const BasicBlock *, BBState> &BBStates,
1497 BlotMapVector<Value *, RRInfo> &Retains) {
1498 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::VisitBottomUp ==\n");
1499
1500 bool NestingDetected = false;
1501 BBState &MyStates = BBStates[BB];
1502
1503 // Merge the states from each successor to compute the initial state
1504 // for the current block.
1505 BBState::edge_iterator SI(MyStates.succ_begin()),
1506 SE(MyStates.succ_end());
1507 if (SI != SE) {
1508 const BasicBlock *Succ = *SI;
1509 auto I = BBStates.find(Val: Succ);
1510 assert(I != BBStates.end());
1511 MyStates.InitFromSucc(Other: I->second);
1512 ++SI;
1513 for (; SI != SE; ++SI) {
1514 Succ = *SI;
1515 I = BBStates.find(Val: Succ);
1516 assert(I != BBStates.end());
1517 MyStates.MergeSucc(Other: I->second);
1518 }
1519 }
1520
1521 LLVM_DEBUG(dbgs() << "Before:\n"
1522 << BBStates[BB] << "\n"
1523 << "Performing Dataflow:\n");
1524
1525 // Visit all the instructions, bottom-up.
1526 for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; --I) {
1527 Instruction *Inst = &*std::prev(x: I);
1528
1529 // Invoke instructions are visited as part of their successors (below).
1530 if (isa<InvokeInst>(Val: Inst))
1531 continue;
1532
1533 LLVM_DEBUG(dbgs() << " Visiting " << *Inst << "\n");
1534
1535 NestingDetected |= VisitInstructionBottomUp(Inst, BB, Retains, MyStates);
1536
1537 // Bail out if the number of pointers being tracked becomes too large so
1538 // that this pass can complete in a reasonable amount of time.
1539 if (MyStates.bottom_up_ptr_list_size() > MaxPtrStates) {
1540 DisableRetainReleasePairing = true;
1541 return false;
1542 }
1543 }
1544
1545 // If there's a predecessor with an invoke, visit the invoke as if it were
1546 // part of this block, since we can't insert code after an invoke in its own
1547 // block, and we don't want to split critical edges.
1548 for (BBState::edge_iterator PI(MyStates.pred_begin()),
1549 PE(MyStates.pred_end()); PI != PE; ++PI) {
1550 BasicBlock *Pred = *PI;
1551 if (InvokeInst *II = dyn_cast<InvokeInst>(Val: &Pred->back()))
1552 NestingDetected |= VisitInstructionBottomUp(Inst: II, BB, Retains, MyStates);
1553 }
1554
1555 LLVM_DEBUG(dbgs() << "\nFinal State:\n" << BBStates[BB] << "\n");
1556
1557 return NestingDetected;
1558}
1559
1560// Fill ReleaseInsertPtToRCIdentityRoots, which is a map from insertion points
1561// to the set of RC identity roots that would be released by the release calls
1562// moved to the insertion points.
1563static void collectReleaseInsertPts(
1564 const BlotMapVector<Value *, RRInfo> &Retains,
1565 DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
1566 &ReleaseInsertPtToRCIdentityRoots) {
1567 for (const auto &P : Retains) {
1568 // Retains is a map from an objc_retain call to a RRInfo of the RC identity
1569 // root of the call. Get the RC identity root of the objc_retain call.
1570 Instruction *Retain = cast<Instruction>(Val: P.first);
1571 Value *Root = GetRCIdentityRoot(V: Retain->getOperand(i: 0));
1572 // Collect all the insertion points of the objc_release calls that release
1573 // the RC identity root of the objc_retain call.
1574 for (const Instruction *InsertPt : P.second.ReverseInsertPts)
1575 ReleaseInsertPtToRCIdentityRoots[InsertPt].insert(Ptr: Root);
1576 }
1577}
1578
1579// Get the RC identity roots from an insertion point of an objc_release call.
1580// Return nullptr if the passed instruction isn't an insertion point.
1581static const SmallPtrSet<const Value *, 2> *
1582getRCIdentityRootsFromReleaseInsertPt(
1583 const Instruction *InsertPt,
1584 const DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
1585 &ReleaseInsertPtToRCIdentityRoots) {
1586 auto I = ReleaseInsertPtToRCIdentityRoots.find(Val: InsertPt);
1587 if (I == ReleaseInsertPtToRCIdentityRoots.end())
1588 return nullptr;
1589 return &I->second;
1590}
1591
1592bool ObjCARCOpt::VisitInstructionTopDown(
1593 Instruction *Inst, DenseMap<Value *, RRInfo> &Releases, BBState &MyStates,
1594 const DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
1595 &ReleaseInsertPtToRCIdentityRoots) {
1596 bool NestingDetected = false;
1597 ARCInstKind Class = GetARCInstKind(V: Inst);
1598 const Value *Arg = nullptr;
1599
1600 // Make sure a call to objc_retain isn't moved past insertion points of calls
1601 // to objc_release.
1602 if (const SmallPtrSet<const Value *, 2> *Roots =
1603 getRCIdentityRootsFromReleaseInsertPt(
1604 InsertPt: Inst, ReleaseInsertPtToRCIdentityRoots))
1605 for (const auto *Root : *Roots) {
1606 TopDownPtrState &S = MyStates.getPtrTopDownState(Arg: Root);
1607 // Disable code motion if the current position is S_Retain to prevent
1608 // moving the objc_retain call past objc_release calls. If it's
1609 // S_CanRelease or larger, it's not necessary to disable code motion as
1610 // the insertion points that prevent the objc_retain call from moving down
1611 // should have been set already.
1612 if (S.GetSeq() == S_Retain)
1613 S.SetCFGHazardAfflicted(true);
1614 }
1615
1616 LLVM_DEBUG(dbgs() << " Class: " << Class << "\n");
1617
1618 switch (Class) {
1619 case ARCInstKind::RetainBlock:
1620 // In OptimizeIndividualCalls, we have strength reduced all optimizable
1621 // objc_retainBlocks to objc_retains. Thus at this point any
1622 // objc_retainBlocks that we see are not optimizable. We need to break since
1623 // a retain can be a potential use.
1624 break;
1625 case ARCInstKind::Retain:
1626 case ARCInstKind::RetainRV: {
1627 Arg = GetArgRCIdentityRoot(Inst);
1628 TopDownPtrState &S = MyStates.getPtrTopDownState(Arg);
1629 NestingDetected |= S.InitTopDown(Kind: Class, I: Inst);
1630 // A retain can be a potential use; proceed to the generic checking
1631 // code below.
1632 break;
1633 }
1634 case ARCInstKind::Release: {
1635 Arg = GetArgRCIdentityRoot(Inst);
1636 TopDownPtrState &S = MyStates.getPtrTopDownState(Arg);
1637 // Try to form a tentative pair in between this release instruction and the
1638 // top down pointers that we are tracking.
1639 if (S.MatchWithRelease(Cache&: MDKindCache, Release: Inst)) {
1640 // If we succeed, copy S's RRInfo into the Release -> {Retain Set
1641 // Map}. Then we clear S.
1642 LLVM_DEBUG(dbgs() << " Matching with: " << *Inst << "\n");
1643 Releases[Inst] = S.GetRRInfo();
1644 S.ClearSequenceProgress();
1645 }
1646 break;
1647 }
1648 case ARCInstKind::AutoreleasepoolPop:
1649 // Conservatively, clear MyStates for all known pointers.
1650 MyStates.clearTopDownPointers();
1651 return false;
1652 case ARCInstKind::AutoreleasepoolPush:
1653 case ARCInstKind::None:
1654 // These can not be uses of
1655 return false;
1656 default:
1657 break;
1658 }
1659
1660 // Consider any other possible effects of this instruction on each
1661 // pointer being tracked.
1662 for (auto MI = MyStates.top_down_ptr_begin(),
1663 ME = MyStates.top_down_ptr_end();
1664 MI != ME; ++MI) {
1665 const Value *Ptr = MI->first;
1666 if (Ptr == Arg)
1667 continue; // Handled above.
1668 TopDownPtrState &S = MI->second;
1669 if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class, BundledRVs: *BundledInsts))
1670 continue;
1671
1672 S.HandlePotentialUse(Inst, Ptr, PA, Class);
1673 }
1674
1675 return NestingDetected;
1676}
1677
1678bool ObjCARCOpt::VisitTopDown(
1679 BasicBlock *BB, DenseMap<const BasicBlock *, BBState> &BBStates,
1680 DenseMap<Value *, RRInfo> &Releases,
1681 const DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
1682 &ReleaseInsertPtToRCIdentityRoots) {
1683 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::VisitTopDown ==\n");
1684 bool NestingDetected = false;
1685 BBState &MyStates = BBStates[BB];
1686
1687 // Merge the states from each predecessor to compute the initial state
1688 // for the current block.
1689 BBState::edge_iterator PI(MyStates.pred_begin()),
1690 PE(MyStates.pred_end());
1691 if (PI != PE) {
1692 const BasicBlock *Pred = *PI;
1693 auto I = BBStates.find(Val: Pred);
1694 assert(I != BBStates.end());
1695 MyStates.InitFromPred(Other: I->second);
1696 ++PI;
1697 for (; PI != PE; ++PI) {
1698 Pred = *PI;
1699 I = BBStates.find(Val: Pred);
1700 assert(I != BBStates.end());
1701 MyStates.MergePred(Other: I->second);
1702 }
1703 }
1704
1705 // Check that BB and MyStates have the same number of predecessors. This
1706 // prevents retain calls that live outside a loop from being moved into the
1707 // loop.
1708 if (!BB->hasNPredecessors(N: MyStates.pred_end() - MyStates.pred_begin()))
1709 for (auto I = MyStates.top_down_ptr_begin(),
1710 E = MyStates.top_down_ptr_end();
1711 I != E; ++I)
1712 I->second.SetCFGHazardAfflicted(true);
1713
1714 LLVM_DEBUG(dbgs() << "Before:\n"
1715 << BBStates[BB] << "\n"
1716 << "Performing Dataflow:\n");
1717
1718 // Visit all the instructions, top-down.
1719 for (Instruction &Inst : *BB) {
1720 LLVM_DEBUG(dbgs() << " Visiting " << Inst << "\n");
1721
1722 NestingDetected |= VisitInstructionTopDown(
1723 Inst: &Inst, Releases, MyStates, ReleaseInsertPtToRCIdentityRoots);
1724
1725 // Bail out if the number of pointers being tracked becomes too large so
1726 // that this pass can complete in a reasonable amount of time.
1727 if (MyStates.top_down_ptr_list_size() > MaxPtrStates) {
1728 DisableRetainReleasePairing = true;
1729 return false;
1730 }
1731 }
1732
1733 LLVM_DEBUG(dbgs() << "\nState Before Checking for CFG Hazards:\n"
1734 << BBStates[BB] << "\n\n");
1735 CheckForCFGHazards(BB, BBStates, MyStates);
1736 LLVM_DEBUG(dbgs() << "Final State:\n" << BBStates[BB] << "\n");
1737 return NestingDetected;
1738}
1739
1740static void
1741ComputePostOrders(Function &F,
1742 SmallVectorImpl<BasicBlock *> &PostOrder,
1743 SmallVectorImpl<BasicBlock *> &ReverseCFGPostOrder,
1744 unsigned NoObjCARCExceptionsMDKind,
1745 DenseMap<const BasicBlock *, BBState> &BBStates) {
1746 /// The visited set, for doing DFS walks.
1747 SmallPtrSet<BasicBlock *, 16> Visited;
1748
1749 // Do DFS, computing the PostOrder.
1750 SmallPtrSet<BasicBlock *, 16> OnStack;
1751 SmallVector<std::pair<BasicBlock *, succ_iterator>, 16> SuccStack;
1752
1753 // Functions always have exactly one entry block, and we don't have
1754 // any other block that we treat like an entry block.
1755 BasicBlock *EntryBB = &F.getEntryBlock();
1756 BBState &MyStates = BBStates[EntryBB];
1757 MyStates.SetAsEntry();
1758 SuccStack.push_back(Elt: std::make_pair(x&: EntryBB, y: succ_begin(BB: EntryBB)));
1759 Visited.insert(Ptr: EntryBB);
1760 OnStack.insert(Ptr: EntryBB);
1761 do {
1762 dfs_next_succ:
1763 BasicBlock *CurrBB = SuccStack.back().first;
1764 succ_iterator SE = succ_end(I: CurrBB->getTerminator());
1765
1766 while (SuccStack.back().second != SE) {
1767 BasicBlock *SuccBB = *SuccStack.back().second++;
1768 if (Visited.insert(Ptr: SuccBB).second) {
1769 SuccStack.push_back(Elt: std::make_pair(x&: SuccBB, y: succ_begin(BB: SuccBB)));
1770 BBStates[CurrBB].addSucc(Succ: SuccBB);
1771 BBState &SuccStates = BBStates[SuccBB];
1772 SuccStates.addPred(Pred: CurrBB);
1773 OnStack.insert(Ptr: SuccBB);
1774 goto dfs_next_succ;
1775 }
1776
1777 if (!OnStack.count(Ptr: SuccBB)) {
1778 BBStates[CurrBB].addSucc(Succ: SuccBB);
1779 BBStates[SuccBB].addPred(Pred: CurrBB);
1780 }
1781 }
1782 OnStack.erase(Ptr: CurrBB);
1783 PostOrder.push_back(Elt: CurrBB);
1784 SuccStack.pop_back();
1785 } while (!SuccStack.empty());
1786
1787 Visited.clear();
1788
1789 // Do reverse-CFG DFS, computing the reverse-CFG PostOrder.
1790 // Functions may have many exits, and there also blocks which we treat
1791 // as exits due to ignored edges.
1792 SmallVector<std::pair<BasicBlock *, BBState::edge_iterator>, 16> PredStack;
1793 for (BasicBlock &ExitBB : F) {
1794 BBState &MyStates = BBStates[&ExitBB];
1795 if (!MyStates.isExit())
1796 continue;
1797
1798 MyStates.SetAsExit();
1799
1800 PredStack.push_back(Elt: std::make_pair(x: &ExitBB, y: MyStates.pred_begin()));
1801 Visited.insert(Ptr: &ExitBB);
1802 while (!PredStack.empty()) {
1803 reverse_dfs_next_succ:
1804 BBState::edge_iterator PE = BBStates[PredStack.back().first].pred_end();
1805 while (PredStack.back().second != PE) {
1806 BasicBlock *BB = *PredStack.back().second++;
1807 if (Visited.insert(Ptr: BB).second) {
1808 PredStack.push_back(Elt: std::make_pair(x&: BB, y: BBStates[BB].pred_begin()));
1809 goto reverse_dfs_next_succ;
1810 }
1811 }
1812 ReverseCFGPostOrder.push_back(Elt: PredStack.pop_back_val().first);
1813 }
1814 }
1815}
1816
1817// Visit the function both top-down and bottom-up.
1818bool ObjCARCOpt::Visit(Function &F,
1819 DenseMap<const BasicBlock *, BBState> &BBStates,
1820 BlotMapVector<Value *, RRInfo> &Retains,
1821 DenseMap<Value *, RRInfo> &Releases) {
1822 // Use reverse-postorder traversals, because we magically know that loops
1823 // will be well behaved, i.e. they won't repeatedly call retain on a single
1824 // pointer without doing a release. We can't use the ReversePostOrderTraversal
1825 // class here because we want the reverse-CFG postorder to consider each
1826 // function exit point, and we want to ignore selected cycle edges.
1827 SmallVector<BasicBlock *, 16> PostOrder;
1828 SmallVector<BasicBlock *, 16> ReverseCFGPostOrder;
1829 ComputePostOrders(F, PostOrder, ReverseCFGPostOrder,
1830 NoObjCARCExceptionsMDKind: MDKindCache.get(ID: ARCMDKindID::NoObjCARCExceptions),
1831 BBStates);
1832
1833 // Use reverse-postorder on the reverse CFG for bottom-up.
1834 bool BottomUpNestingDetected = false;
1835 for (BasicBlock *BB : llvm::reverse(C&: ReverseCFGPostOrder)) {
1836 BottomUpNestingDetected |= VisitBottomUp(BB, BBStates, Retains);
1837 if (DisableRetainReleasePairing)
1838 return false;
1839 }
1840
1841 DenseMap<const Instruction *, SmallPtrSet<const Value *, 2>>
1842 ReleaseInsertPtToRCIdentityRoots;
1843 collectReleaseInsertPts(Retains, ReleaseInsertPtToRCIdentityRoots);
1844
1845 // Use reverse-postorder for top-down.
1846 bool TopDownNestingDetected = false;
1847 for (BasicBlock *BB : llvm::reverse(C&: PostOrder)) {
1848 TopDownNestingDetected |=
1849 VisitTopDown(BB, BBStates, Releases, ReleaseInsertPtToRCIdentityRoots);
1850 if (DisableRetainReleasePairing)
1851 return false;
1852 }
1853
1854 return TopDownNestingDetected && BottomUpNestingDetected;
1855}
1856
1857/// Move the calls in RetainsToMove and ReleasesToMove.
1858void ObjCARCOpt::MoveCalls(Value *Arg, RRInfo &RetainsToMove,
1859 RRInfo &ReleasesToMove,
1860 BlotMapVector<Value *, RRInfo> &Retains,
1861 DenseMap<Value *, RRInfo> &Releases,
1862 SmallVectorImpl<Instruction *> &DeadInsts,
1863 Module *M) {
1864 LLVM_DEBUG(dbgs() << "== ObjCARCOpt::MoveCalls ==\n");
1865
1866 // Insert the new retain and release calls.
1867 for (Instruction *InsertPt : ReleasesToMove.ReverseInsertPts) {
1868 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Retain);
1869 SmallVector<OperandBundleDef, 1> BundleList;
1870 addOpBundleForFunclet(BB: InsertPt->getParent(), OpBundles&: BundleList);
1871 CallInst *Call =
1872 CallInst::Create(Func: Decl, Args: Arg, Bundles: BundleList, NameStr: "", InsertBefore: InsertPt->getIterator());
1873 Call->setDoesNotThrow();
1874 Call->setTailCall();
1875
1876 LLVM_DEBUG(dbgs() << "Inserting new Retain: " << *Call
1877 << "\n"
1878 "At insertion point: "
1879 << *InsertPt << "\n");
1880 }
1881 for (Instruction *InsertPt : RetainsToMove.ReverseInsertPts) {
1882 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Release);
1883 SmallVector<OperandBundleDef, 1> BundleList;
1884 addOpBundleForFunclet(BB: InsertPt->getParent(), OpBundles&: BundleList);
1885 CallInst *Call =
1886 CallInst::Create(Func: Decl, Args: Arg, Bundles: BundleList, NameStr: "", InsertBefore: InsertPt->getIterator());
1887 // Attach a clang.imprecise_release metadata tag, if appropriate.
1888 if (MDNode *M = ReleasesToMove.ReleaseMetadata)
1889 Call->setMetadata(KindID: MDKindCache.get(ID: ARCMDKindID::ImpreciseRelease), Node: M);
1890 Call->setDoesNotThrow();
1891 if (ReleasesToMove.IsTailCallRelease)
1892 Call->setTailCall();
1893
1894 LLVM_DEBUG(dbgs() << "Inserting new Release: " << *Call
1895 << "\n"
1896 "At insertion point: "
1897 << *InsertPt << "\n");
1898 }
1899
1900 // Delete the original retain and release calls.
1901 for (Instruction *OrigRetain : RetainsToMove.Calls) {
1902 Retains.blot(Key: OrigRetain);
1903 DeadInsts.push_back(Elt: OrigRetain);
1904 LLVM_DEBUG(dbgs() << "Deleting retain: " << *OrigRetain << "\n");
1905 }
1906 for (Instruction *OrigRelease : ReleasesToMove.Calls) {
1907 Releases.erase(Val: OrigRelease);
1908 DeadInsts.push_back(Elt: OrigRelease);
1909 LLVM_DEBUG(dbgs() << "Deleting release: " << *OrigRelease << "\n");
1910 }
1911}
1912
1913bool ObjCARCOpt::PairUpRetainsAndReleases(
1914 DenseMap<const BasicBlock *, BBState> &BBStates,
1915 BlotMapVector<Value *, RRInfo> &Retains,
1916 DenseMap<Value *, RRInfo> &Releases, Module *M,
1917 Instruction *Retain,
1918 SmallVectorImpl<Instruction *> &DeadInsts, RRInfo &RetainsToMove,
1919 RRInfo &ReleasesToMove, Value *Arg, bool KnownSafe,
1920 bool &AnyPairsCompletelyEliminated) {
1921 // If a pair happens in a region where it is known that the reference count
1922 // is already incremented, we can similarly ignore possible decrements unless
1923 // we are dealing with a retainable object with multiple provenance sources.
1924 bool KnownSafeTD = true, KnownSafeBU = true;
1925 bool CFGHazardAfflicted = false;
1926
1927 // Connect the dots between the top-down-collected RetainsToMove and
1928 // bottom-up-collected ReleasesToMove to form sets of related calls.
1929 // This is an iterative process so that we connect multiple releases
1930 // to multiple retains if needed.
1931 unsigned OldDelta = 0;
1932 unsigned NewDelta = 0;
1933 unsigned OldCount = 0;
1934 unsigned NewCount = 0;
1935 bool FirstRelease = true;
1936 for (SmallVector<Instruction *, 4> NewRetains{Retain};;) {
1937 SmallVector<Instruction *, 4> NewReleases;
1938 for (Instruction *NewRetain : NewRetains) {
1939 auto It = Retains.find(Key: NewRetain);
1940 assert(It != Retains.end());
1941 const RRInfo &NewRetainRRI = It->second;
1942 KnownSafeTD &= NewRetainRRI.KnownSafe;
1943 CFGHazardAfflicted |= NewRetainRRI.CFGHazardAfflicted;
1944 for (Instruction *NewRetainRelease : NewRetainRRI.Calls) {
1945 auto Jt = Releases.find(Val: NewRetainRelease);
1946 if (Jt == Releases.end())
1947 return false;
1948 const RRInfo &NewRetainReleaseRRI = Jt->second;
1949
1950 // If the release does not have a reference to the retain as well,
1951 // something happened which is unaccounted for. Do not do anything.
1952 //
1953 // This can happen if we catch an additive overflow during path count
1954 // merging.
1955 if (!NewRetainReleaseRRI.Calls.count(Ptr: NewRetain))
1956 return false;
1957
1958 if (ReleasesToMove.Calls.insert(Ptr: NewRetainRelease).second) {
1959 // If we overflow when we compute the path count, don't remove/move
1960 // anything.
1961 const BBState &NRRBBState = BBStates[NewRetainRelease->getParent()];
1962 unsigned PathCount = BBState::OverflowOccurredValue;
1963 if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
1964 return false;
1965 assert(PathCount != BBState::OverflowOccurredValue &&
1966 "PathCount at this point can not be "
1967 "OverflowOccurredValue.");
1968 OldDelta -= PathCount;
1969
1970 // Merge the ReleaseMetadata and IsTailCallRelease values.
1971 if (FirstRelease) {
1972 ReleasesToMove.ReleaseMetadata =
1973 NewRetainReleaseRRI.ReleaseMetadata;
1974 ReleasesToMove.IsTailCallRelease =
1975 NewRetainReleaseRRI.IsTailCallRelease;
1976 FirstRelease = false;
1977 } else {
1978 if (ReleasesToMove.ReleaseMetadata !=
1979 NewRetainReleaseRRI.ReleaseMetadata)
1980 ReleasesToMove.ReleaseMetadata = nullptr;
1981 if (ReleasesToMove.IsTailCallRelease !=
1982 NewRetainReleaseRRI.IsTailCallRelease)
1983 ReleasesToMove.IsTailCallRelease = false;
1984 }
1985
1986 // Collect the optimal insertion points.
1987 if (!KnownSafe)
1988 for (Instruction *RIP : NewRetainReleaseRRI.ReverseInsertPts) {
1989 if (ReleasesToMove.ReverseInsertPts.insert(Ptr: RIP).second) {
1990 // If we overflow when we compute the path count, don't
1991 // remove/move anything.
1992 const BBState &RIPBBState = BBStates[RIP->getParent()];
1993 PathCount = BBState::OverflowOccurredValue;
1994 if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
1995 return false;
1996 assert(PathCount != BBState::OverflowOccurredValue &&
1997 "PathCount at this point can not be "
1998 "OverflowOccurredValue.");
1999 NewDelta -= PathCount;
2000 }
2001 }
2002 NewReleases.push_back(Elt: NewRetainRelease);
2003 }
2004 }
2005 }
2006 NewRetains.clear();
2007 if (NewReleases.empty()) break;
2008
2009 // Back the other way.
2010 for (Instruction *NewRelease : NewReleases) {
2011 auto It = Releases.find(Val: NewRelease);
2012 assert(It != Releases.end());
2013 const RRInfo &NewReleaseRRI = It->second;
2014 KnownSafeBU &= NewReleaseRRI.KnownSafe;
2015 CFGHazardAfflicted |= NewReleaseRRI.CFGHazardAfflicted;
2016 for (Instruction *NewReleaseRetain : NewReleaseRRI.Calls) {
2017 auto Jt = Retains.find(Key: NewReleaseRetain);
2018 if (Jt == Retains.end())
2019 return false;
2020 const RRInfo &NewReleaseRetainRRI = Jt->second;
2021
2022 // If the retain does not have a reference to the release as well,
2023 // something happened which is unaccounted for. Do not do anything.
2024 //
2025 // This can happen if we catch an additive overflow during path count
2026 // merging.
2027 if (!NewReleaseRetainRRI.Calls.count(Ptr: NewRelease))
2028 return false;
2029
2030 if (RetainsToMove.Calls.insert(Ptr: NewReleaseRetain).second) {
2031 // If we overflow when we compute the path count, don't remove/move
2032 // anything.
2033 const BBState &NRRBBState = BBStates[NewReleaseRetain->getParent()];
2034 unsigned PathCount = BBState::OverflowOccurredValue;
2035 if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
2036 return false;
2037 assert(PathCount != BBState::OverflowOccurredValue &&
2038 "PathCount at this point can not be "
2039 "OverflowOccurredValue.");
2040 OldDelta += PathCount;
2041 OldCount += PathCount;
2042
2043 // Collect the optimal insertion points.
2044 if (!KnownSafe)
2045 for (Instruction *RIP : NewReleaseRetainRRI.ReverseInsertPts) {
2046 if (RetainsToMove.ReverseInsertPts.insert(Ptr: RIP).second) {
2047 // If we overflow when we compute the path count, don't
2048 // remove/move anything.
2049 const BBState &RIPBBState = BBStates[RIP->getParent()];
2050
2051 PathCount = BBState::OverflowOccurredValue;
2052 if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
2053 return false;
2054 assert(PathCount != BBState::OverflowOccurredValue &&
2055 "PathCount at this point can not be "
2056 "OverflowOccurredValue.");
2057 NewDelta += PathCount;
2058 NewCount += PathCount;
2059 }
2060 }
2061 NewRetains.push_back(Elt: NewReleaseRetain);
2062 }
2063 }
2064 }
2065 if (NewRetains.empty()) break;
2066 }
2067
2068 // We can only remove pointers if we are known safe in both directions.
2069 bool UnconditionallySafe = KnownSafeTD && KnownSafeBU;
2070 if (UnconditionallySafe) {
2071 RetainsToMove.ReverseInsertPts.clear();
2072 ReleasesToMove.ReverseInsertPts.clear();
2073 NewCount = 0;
2074 } else {
2075 // Determine whether the new insertion points we computed preserve the
2076 // balance of retain and release calls through the program.
2077 // TODO: If the fully aggressive solution isn't valid, try to find a
2078 // less aggressive solution which is.
2079 if (NewDelta != 0)
2080 return false;
2081
2082 // At this point, we are not going to remove any RR pairs, but we still are
2083 // able to move RR pairs. If one of our pointers is afflicted with
2084 // CFGHazards, we cannot perform such code motion so exit early.
2085 const bool WillPerformCodeMotion =
2086 !RetainsToMove.ReverseInsertPts.empty() ||
2087 !ReleasesToMove.ReverseInsertPts.empty();
2088 if (CFGHazardAfflicted && WillPerformCodeMotion)
2089 return false;
2090 }
2091
2092 // Determine whether the original call points are balanced in the retain and
2093 // release calls through the program. If not, conservatively don't touch
2094 // them.
2095 // TODO: It's theoretically possible to do code motion in this case, as
2096 // long as the existing imbalances are maintained.
2097 if (OldDelta != 0)
2098 return false;
2099
2100 Changed = true;
2101 assert(OldCount != 0 && "Unreachable code?");
2102 NumRRs += OldCount - NewCount;
2103 // Set to true if we completely removed any RR pairs.
2104 AnyPairsCompletelyEliminated = NewCount == 0;
2105
2106 // We can move calls!
2107 return true;
2108}
2109
2110/// Identify pairings between the retains and releases, and delete and/or move
2111/// them.
2112bool ObjCARCOpt::PerformCodePlacement(
2113 DenseMap<const BasicBlock *, BBState> &BBStates,
2114 BlotMapVector<Value *, RRInfo> &Retains,
2115 DenseMap<Value *, RRInfo> &Releases, Module *M) {
2116 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::PerformCodePlacement ==\n");
2117
2118 bool AnyPairsCompletelyEliminated = false;
2119 SmallVector<Instruction *, 8> DeadInsts;
2120
2121 // Visit each retain.
2122 for (BlotMapVector<Value *, RRInfo>::const_iterator I = Retains.begin(),
2123 E = Retains.end();
2124 I != E; ++I) {
2125 Value *V = I->first;
2126 if (!V) continue; // blotted
2127
2128 Instruction *Retain = cast<Instruction>(Val: V);
2129
2130 LLVM_DEBUG(dbgs() << "Visiting: " << *Retain << "\n");
2131
2132 Value *Arg = GetArgRCIdentityRoot(Inst: Retain);
2133
2134 // If the object being released is in static or stack storage, we know it's
2135 // not being managed by ObjC reference counting, so we can delete pairs
2136 // regardless of what possible decrements or uses lie between them.
2137 bool KnownSafe = isa<Constant>(Val: Arg) || isa<AllocaInst>(Val: Arg);
2138
2139 // A constant pointer can't be pointing to an object on the heap. It may
2140 // be reference-counted, but it won't be deleted.
2141 if (const LoadInst *LI = dyn_cast<LoadInst>(Val: Arg))
2142 if (const GlobalVariable *GV =
2143 dyn_cast<GlobalVariable>(
2144 Val: GetRCIdentityRoot(V: LI->getPointerOperand())))
2145 if (GV->isConstant())
2146 KnownSafe = true;
2147
2148 // Connect the dots between the top-down-collected RetainsToMove and
2149 // bottom-up-collected ReleasesToMove to form sets of related calls.
2150 RRInfo RetainsToMove, ReleasesToMove;
2151
2152 bool PerformMoveCalls = PairUpRetainsAndReleases(
2153 BBStates, Retains, Releases, M, Retain, DeadInsts,
2154 RetainsToMove, ReleasesToMove, Arg, KnownSafe,
2155 AnyPairsCompletelyEliminated);
2156
2157 if (PerformMoveCalls) {
2158 // Ok, everything checks out and we're all set. Let's move/delete some
2159 // code!
2160 MoveCalls(Arg, RetainsToMove, ReleasesToMove,
2161 Retains, Releases, DeadInsts, M);
2162 }
2163 }
2164
2165 // Now that we're done moving everything, we can delete the newly dead
2166 // instructions, as we no longer need them as insert points.
2167 while (!DeadInsts.empty())
2168 EraseInstruction(CI: DeadInsts.pop_back_val());
2169
2170 return AnyPairsCompletelyEliminated;
2171}
2172
2173/// Weak pointer optimizations.
2174void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
2175 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeWeakCalls ==\n");
2176
2177 // First, do memdep-style RLE and S2L optimizations. We can't use memdep
2178 // itself because it uses AliasAnalysis and we need to do provenance
2179 // queries instead.
2180 for (inst_iterator I = inst_begin(F: &F), E = inst_end(F: &F); I != E; ) {
2181 Instruction *Inst = &*I++;
2182
2183 LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
2184
2185 ARCInstKind Class = GetBasicARCInstKind(V: Inst);
2186 if (Class != ARCInstKind::LoadWeak &&
2187 Class != ARCInstKind::LoadWeakRetained)
2188 continue;
2189
2190 // Delete objc_loadWeak calls with no users.
2191 if (Class == ARCInstKind::LoadWeak && Inst->use_empty()) {
2192 Inst->eraseFromParent();
2193 Changed = true;
2194 continue;
2195 }
2196
2197 // TODO: For now, just look for an earlier available version of this value
2198 // within the same block. Theoretically, we could do memdep-style non-local
2199 // analysis too, but that would want caching. A better approach would be to
2200 // use the technique that EarlyCSE uses.
2201 inst_iterator Current = std::prev(x: I);
2202 BasicBlock *CurrentBB = &*Current.getBasicBlockIterator();
2203 for (BasicBlock::iterator B = CurrentBB->begin(),
2204 J = Current.getInstructionIterator();
2205 J != B; --J) {
2206 Instruction *EarlierInst = &*std::prev(x: J);
2207 ARCInstKind EarlierClass = GetARCInstKind(V: EarlierInst);
2208 switch (EarlierClass) {
2209 case ARCInstKind::LoadWeak:
2210 case ARCInstKind::LoadWeakRetained: {
2211 // If this is loading from the same pointer, replace this load's value
2212 // with that one.
2213 CallInst *Call = cast<CallInst>(Val: Inst);
2214 CallInst *EarlierCall = cast<CallInst>(Val: EarlierInst);
2215 Value *Arg = Call->getArgOperand(i: 0);
2216 Value *EarlierArg = EarlierCall->getArgOperand(i: 0);
2217 switch (PA.getAA()->alias(V1: Arg, V2: EarlierArg)) {
2218 case AliasResult::MustAlias:
2219 Changed = true;
2220 // If the load has a builtin retain, insert a plain retain for it.
2221 if (Class == ARCInstKind::LoadWeakRetained) {
2222 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Retain);
2223 CallInst *CI =
2224 CallInst::Create(Func: Decl, Args: EarlierCall, NameStr: "", InsertBefore: Call->getIterator());
2225 CI->setTailCall();
2226 }
2227 // Zap the fully redundant load.
2228 Call->replaceAllUsesWith(V: EarlierCall);
2229 Call->eraseFromParent();
2230 goto clobbered;
2231 case AliasResult::MayAlias:
2232 case AliasResult::PartialAlias:
2233 goto clobbered;
2234 case AliasResult::NoAlias:
2235 break;
2236 }
2237 break;
2238 }
2239 case ARCInstKind::StoreWeak:
2240 case ARCInstKind::InitWeak: {
2241 // If this is storing to the same pointer and has the same size etc.
2242 // replace this load's value with the stored value.
2243 CallInst *Call = cast<CallInst>(Val: Inst);
2244 CallInst *EarlierCall = cast<CallInst>(Val: EarlierInst);
2245 Value *Arg = Call->getArgOperand(i: 0);
2246 Value *EarlierArg = EarlierCall->getArgOperand(i: 0);
2247 switch (PA.getAA()->alias(V1: Arg, V2: EarlierArg)) {
2248 case AliasResult::MustAlias:
2249 Changed = true;
2250 // If the load has a builtin retain, insert a plain retain for it.
2251 if (Class == ARCInstKind::LoadWeakRetained) {
2252 Function *Decl = EP.get(kind: ARCRuntimeEntryPointKind::Retain);
2253 CallInst *CI =
2254 CallInst::Create(Func: Decl, Args: EarlierCall, NameStr: "", InsertBefore: Call->getIterator());
2255 CI->setTailCall();
2256 }
2257 // Zap the fully redundant load.
2258 Call->replaceAllUsesWith(V: EarlierCall->getArgOperand(i: 1));
2259 Call->eraseFromParent();
2260 goto clobbered;
2261 case AliasResult::MayAlias:
2262 case AliasResult::PartialAlias:
2263 goto clobbered;
2264 case AliasResult::NoAlias:
2265 break;
2266 }
2267 break;
2268 }
2269 case ARCInstKind::MoveWeak:
2270 case ARCInstKind::CopyWeak:
2271 // TOOD: Grab the copied value.
2272 goto clobbered;
2273 case ARCInstKind::AutoreleasepoolPush:
2274 case ARCInstKind::None:
2275 case ARCInstKind::IntrinsicUser:
2276 case ARCInstKind::User:
2277 // Weak pointers are only modified through the weak entry points
2278 // (and arbitrary calls, which could call the weak entry points).
2279 break;
2280 default:
2281 // Anything else could modify the weak pointer.
2282 goto clobbered;
2283 }
2284 }
2285 clobbered:;
2286 }
2287
2288 // Then, for each destroyWeak with an alloca operand, check to see if
2289 // the alloca and all its users can be zapped.
2290 for (Instruction &Inst : llvm::make_early_inc_range(Range: instructions(F))) {
2291 ARCInstKind Class = GetBasicARCInstKind(V: &Inst);
2292 if (Class != ARCInstKind::DestroyWeak)
2293 continue;
2294
2295 CallInst *Call = cast<CallInst>(Val: &Inst);
2296 Value *Arg = Call->getArgOperand(i: 0);
2297 if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Val: Arg)) {
2298 for (User *U : Alloca->users()) {
2299 const Instruction *UserInst = cast<Instruction>(Val: U);
2300 switch (GetBasicARCInstKind(V: UserInst)) {
2301 case ARCInstKind::InitWeak:
2302 case ARCInstKind::StoreWeak:
2303 case ARCInstKind::DestroyWeak:
2304 continue;
2305 default:
2306 goto done;
2307 }
2308 }
2309 Changed = true;
2310 for (User *U : llvm::make_early_inc_range(Range: Alloca->users())) {
2311 CallInst *UserInst = cast<CallInst>(Val: U);
2312 switch (GetBasicARCInstKind(V: UserInst)) {
2313 case ARCInstKind::InitWeak:
2314 case ARCInstKind::StoreWeak:
2315 // These functions return their second argument.
2316 UserInst->replaceAllUsesWith(V: UserInst->getArgOperand(i: 1));
2317 break;
2318 case ARCInstKind::DestroyWeak:
2319 // No return value.
2320 break;
2321 default:
2322 llvm_unreachable("alloca really is used!");
2323 }
2324 UserInst->eraseFromParent();
2325 }
2326 Alloca->eraseFromParent();
2327 done:;
2328 }
2329 }
2330}
2331
2332/// Identify program paths which execute sequences of retains and releases which
2333/// can be eliminated.
2334bool ObjCARCOpt::OptimizeSequences(Function &F) {
2335 // Releases, Retains - These are used to store the results of the main flow
2336 // analysis. These use Value* as the key instead of Instruction* so that the
2337 // map stays valid when we get around to rewriting code and calls get
2338 // replaced by arguments.
2339 DenseMap<Value *, RRInfo> Releases;
2340 BlotMapVector<Value *, RRInfo> Retains;
2341
2342 // This is used during the traversal of the function to track the
2343 // states for each identified object at each block.
2344 DenseMap<const BasicBlock *, BBState> BBStates;
2345
2346 // Analyze the CFG of the function, and all instructions.
2347 bool NestingDetected = Visit(F, BBStates, Retains, Releases);
2348
2349 if (DisableRetainReleasePairing)
2350 return false;
2351
2352 // Transform.
2353 bool AnyPairsCompletelyEliminated = PerformCodePlacement(BBStates, Retains,
2354 Releases,
2355 M: F.getParent());
2356
2357 return AnyPairsCompletelyEliminated && NestingDetected;
2358}
2359
2360/// Check if there is a dependent call earlier that does not have anything in
2361/// between the Retain and the call that can affect the reference count of their
2362/// shared pointer argument. Note that Retain need not be in BB.
2363static CallInst *HasSafePathToPredecessorCall(const Value *Arg,
2364 Instruction *Retain,
2365 ProvenanceAnalysis &PA) {
2366 auto *Call = dyn_cast_or_null<CallInst>(Val: findSingleDependency(
2367 Flavor: CanChangeRetainCount, Arg, StartBB: Retain->getParent(), StartInst: Retain, PA));
2368
2369 // Check that the pointer is the return value of the call.
2370 if (!Call || Arg != Call)
2371 return nullptr;
2372
2373 // Check that the call is a regular call.
2374 ARCInstKind Class = GetBasicARCInstKind(V: Call);
2375 return Class == ARCInstKind::CallOrUser || Class == ARCInstKind::Call
2376 ? Call
2377 : nullptr;
2378}
2379
2380/// Find a dependent retain that precedes the given autorelease for which there
2381/// is nothing in between the two instructions that can affect the ref count of
2382/// Arg.
2383static CallInst *
2384FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
2385 Instruction *Autorelease,
2386 ProvenanceAnalysis &PA) {
2387 auto *Retain = dyn_cast_or_null<CallInst>(
2388 Val: findSingleDependency(Flavor: CanChangeRetainCount, Arg, StartBB: BB, StartInst: Autorelease, PA));
2389
2390 // Check that we found a retain with the same argument.
2391 if (!Retain || !IsRetain(Class: GetBasicARCInstKind(V: Retain)) ||
2392 GetArgRCIdentityRoot(Inst: Retain) != Arg) {
2393 return nullptr;
2394 }
2395
2396 return Retain;
2397}
2398
2399/// Look for an ``autorelease'' instruction dependent on Arg such that there are
2400/// no instructions dependent on Arg that need a positive ref count in between
2401/// the autorelease and the ret.
2402static CallInst *FindPredecessorAutoreleaseWithSafePath(
2403 const Value *Arg, BasicBlock *BB, ReturnInst *Ret, ProvenanceAnalysis &PA) {
2404 auto *Autorelease = dyn_cast_or_null<CallInst>(
2405 Val: findSingleDependency(Flavor: NeedsPositiveRetainCount, Arg, StartBB: BB, StartInst: Ret, PA));
2406
2407 if (!Autorelease)
2408 return nullptr;
2409 ARCInstKind AutoreleaseClass = GetBasicARCInstKind(V: Autorelease);
2410 if (!IsAutorelease(Class: AutoreleaseClass))
2411 return nullptr;
2412 if (GetArgRCIdentityRoot(Inst: Autorelease) != Arg)
2413 return nullptr;
2414
2415 return Autorelease;
2416}
2417
2418/// Look for this pattern:
2419/// \code
2420/// %call = call i8* @something(...)
2421/// %2 = call i8* @objc_retain(i8* %call)
2422/// %3 = call i8* @objc_autorelease(i8* %2)
2423/// ret i8* %3
2424/// \endcode
2425/// And delete the retain and autorelease.
2426void ObjCARCOpt::OptimizeReturns(Function &F) {
2427 if (!F.getReturnType()->isPointerTy())
2428 return;
2429
2430 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeReturns ==\n");
2431
2432 for (BasicBlock &BB: F) {
2433 ReturnInst *Ret = dyn_cast<ReturnInst>(Val: &BB.back());
2434 if (!Ret)
2435 continue;
2436
2437 LLVM_DEBUG(dbgs() << "Visiting: " << *Ret << "\n");
2438
2439 const Value *Arg = GetRCIdentityRoot(V: Ret->getOperand(i_nocapture: 0));
2440
2441 // Look for an ``autorelease'' instruction that is a predecessor of Ret and
2442 // dependent on Arg such that there are no instructions dependent on Arg
2443 // that need a positive ref count in between the autorelease and Ret.
2444 CallInst *Autorelease =
2445 FindPredecessorAutoreleaseWithSafePath(Arg, BB: &BB, Ret, PA);
2446
2447 if (!Autorelease)
2448 continue;
2449
2450 CallInst *Retain = FindPredecessorRetainWithSafePath(
2451 Arg, BB: Autorelease->getParent(), Autorelease, PA);
2452
2453 if (!Retain)
2454 continue;
2455
2456 // Check that there is nothing that can affect the reference count
2457 // between the retain and the call. Note that Retain need not be in BB.
2458 CallInst *Call = HasSafePathToPredecessorCall(Arg, Retain, PA);
2459
2460 // Don't remove retainRV/autoreleaseRV pairs if the call isn't a tail call.
2461 if (!Call ||
2462 (!Call->isTailCall() &&
2463 GetBasicARCInstKind(V: Retain) == ARCInstKind::RetainRV &&
2464 GetBasicARCInstKind(V: Autorelease) == ARCInstKind::AutoreleaseRV))
2465 continue;
2466
2467 // If so, we can zap the retain and autorelease.
2468 Changed = true;
2469 ++NumRets;
2470 LLVM_DEBUG(dbgs() << "Erasing: " << *Retain << "\nErasing: " << *Autorelease
2471 << "\n");
2472 BundledInsts->eraseInst(CI: Retain);
2473 FollowingPoolPopCache.erase(Val: Autorelease);
2474 EraseInstruction(CI: Autorelease);
2475 }
2476}
2477
2478#ifndef NDEBUG
2479void
2480ObjCARCOpt::GatherStatistics(Function &F, bool AfterOptimization) {
2481 Statistic &NumRetains =
2482 AfterOptimization ? NumRetainsAfterOpt : NumRetainsBeforeOpt;
2483 Statistic &NumReleases =
2484 AfterOptimization ? NumReleasesAfterOpt : NumReleasesBeforeOpt;
2485
2486 for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
2487 Instruction *Inst = &*I++;
2488 switch (GetBasicARCInstKind(Inst)) {
2489 default:
2490 break;
2491 case ARCInstKind::Retain:
2492 ++NumRetains;
2493 break;
2494 case ARCInstKind::Release:
2495 ++NumReleases;
2496 break;
2497 }
2498 }
2499}
2500#endif
2501
2502void ObjCARCOpt::init(Function &F) {
2503 if (!EnableARCOpts)
2504 return;
2505
2506 // Intuitively, objc_retain and others are nocapture, however in practice
2507 // they are not, because they return their argument value. And objc_release
2508 // calls finalizers which can have arbitrary side effects.
2509 MDKindCache.init(Mod: F.getParent());
2510
2511 // Initialize our runtime entry point cache.
2512 EP.init(M: F.getParent());
2513
2514 // Compute which blocks are in which funclet.
2515 if (F.hasPersonalityFn() &&
2516 isScopedEHPersonality(Pers: classifyEHPersonality(Pers: F.getPersonalityFn())))
2517 BlockEHColors = colorEHFunclets(F);
2518}
2519
2520bool ObjCARCOpt::run(Function &F, AAResults &AA) {
2521 if (!EnableARCOpts)
2522 return false;
2523
2524 Changed = CFGChanged = false;
2525 BundledRetainClaimRVs BRV(EP, /*ContractPass=*/false, /*UseClaimRV=*/false);
2526 BundledInsts = &BRV;
2527
2528 LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName()
2529 << " >>>"
2530 "\n");
2531
2532 std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT: nullptr);
2533 Changed |= R.first;
2534 CFGChanged |= R.second;
2535
2536 PA.setAA(&AA);
2537
2538#ifndef NDEBUG
2539 if (AreStatisticsEnabled()) {
2540 GatherStatistics(F, false);
2541 }
2542#endif
2543
2544 // This pass performs several distinct transformations. As a compile-time aid
2545 // when compiling code that isn't ObjC, skip these if the relevant ObjC
2546 // library functions aren't declared.
2547
2548 // Preliminary optimizations. This also computes UsedInThisFunction.
2549 OptimizeIndividualCalls(F);
2550
2551 // Optimizations for weak pointers.
2552 if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::LoadWeak)) |
2553 (1 << unsigned(ARCInstKind::LoadWeakRetained)) |
2554 (1 << unsigned(ARCInstKind::StoreWeak)) |
2555 (1 << unsigned(ARCInstKind::InitWeak)) |
2556 (1 << unsigned(ARCInstKind::CopyWeak)) |
2557 (1 << unsigned(ARCInstKind::MoveWeak)) |
2558 (1 << unsigned(ARCInstKind::DestroyWeak))))
2559 OptimizeWeakCalls(F);
2560
2561 // Optimizations for retain+release pairs.
2562 if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::Retain)) |
2563 (1 << unsigned(ARCInstKind::RetainRV)) |
2564 (1 << unsigned(ARCInstKind::RetainBlock))))
2565 if (UsedInThisFunction & (1 << unsigned(ARCInstKind::Release)))
2566 // Run OptimizeSequences until it either stops making changes or
2567 // no retain+release pair nesting is detected.
2568 while (OptimizeSequences(F)) {}
2569
2570 // Optimizations if objc_autorelease is used.
2571 if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::Autorelease)) |
2572 (1 << unsigned(ARCInstKind::AutoreleaseRV))))
2573 OptimizeReturns(F);
2574
2575 // Optimizations for autorelease pools.
2576 if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::AutoreleasepoolPush)) |
2577 (1 << unsigned(ARCInstKind::AutoreleasepoolPop))))
2578 OptimizeAutoreleasePools(F);
2579
2580 // Gather statistics after optimization.
2581#ifndef NDEBUG
2582 if (AreStatisticsEnabled()) {
2583 GatherStatistics(F, true);
2584 }
2585#endif
2586
2587 LLVM_DEBUG(dbgs() << "\n");
2588
2589 return Changed;
2590}
2591
2592/// Interprocedurally determine if calls made by the given call site can
2593/// possibly produce autoreleases.
2594static bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
2595 if (CB.onlyReadsMemory())
2596 return false;
2597
2598 // This recursion depth limit is arbitrary. It's just great
2599 // enough to cover known interesting testcases.
2600 if (Depth > 5)
2601 return true;
2602
2603 if (const Function *Callee = CB.getCalledFunction()) {
2604 if (!Callee->hasExactDefinition())
2605 return true;
2606
2607 for (const BasicBlock &BB : *Callee) {
2608 // Track nested autorelease pools within a basic block. Autoreleases
2609 // inside a pool are drained before the pool ends; only effects at block
2610 // scope (empty stack) or in a pool not closed in the block matter.
2611 SmallVector<bool, 4> PoolStack;
2612 for (const Instruction &I : BB) {
2613 ARCInstKind InstKind = GetBasicARCInstKind(V: &I);
2614 switch (InstKind) {
2615 case ARCInstKind::AutoreleasepoolPush:
2616 PoolStack.push_back(Elt: false);
2617 break;
2618
2619 case ARCInstKind::AutoreleasepoolPop:
2620 if (!PoolStack.empty())
2621 PoolStack.pop_back();
2622 break;
2623
2624 case ARCInstKind::Autorelease:
2625 case ARCInstKind::AutoreleaseRV:
2626 case ARCInstKind::FusedRetainAutorelease:
2627 case ARCInstKind::FusedRetainAutoreleaseRV:
2628 case ARCInstKind::LoadWeak:
2629 // These may produce autoreleases
2630 if (PoolStack.empty())
2631 return true;
2632 PoolStack.back() = true;
2633 break;
2634
2635 case ARCInstKind::Retain:
2636 case ARCInstKind::RetainRV:
2637 case ARCInstKind::UnsafeClaimRV:
2638 case ARCInstKind::RetainBlock:
2639 case ARCInstKind::Release:
2640 case ARCInstKind::NoopCast:
2641 case ARCInstKind::LoadWeakRetained:
2642 case ARCInstKind::StoreWeak:
2643 case ARCInstKind::InitWeak:
2644 case ARCInstKind::MoveWeak:
2645 case ARCInstKind::CopyWeak:
2646 case ARCInstKind::DestroyWeak:
2647 case ARCInstKind::StoreStrong:
2648 // These ObjC runtime functions don't produce autoreleases
2649 break;
2650
2651 case ARCInstKind::CallOrUser:
2652 case ARCInstKind::Call:
2653 // For non-ObjC function calls, recursively analyze.
2654 if (MayAutorelease(CB: cast<CallBase>(Val: I), Depth: Depth + 1)) {
2655 if (PoolStack.empty())
2656 return true;
2657 PoolStack.back() = true;
2658 }
2659 break;
2660
2661 case ARCInstKind::IntrinsicUser:
2662 case ARCInstKind::User:
2663 case ARCInstKind::None:
2664 // These are not relevant for autorelease analysis
2665 break;
2666 }
2667 }
2668 // If the block ended with an un-popped pool containing an autorelease,
2669 // that autorelease escapes the block.
2670 if (!PoolStack.empty() && llvm::is_contained(Range&: PoolStack, Element: true))
2671 return true;
2672 }
2673 return false;
2674 }
2675
2676 return true;
2677}
2678
2679/// Optimize autorelease pools by eliminating empty push/pop pairs.
2680void ObjCARCOpt::OptimizeAutoreleasePools(Function &F) {
2681 LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeAutoreleasePools ==\n");
2682
2683 OptimizationRemarkEmitter ORE(&F);
2684
2685 // Process each basic block independently.
2686 // TODO: Can we optimize inter-block autorelease pool pairs?
2687 // This would involve tracking autorelease pool state across blocks.
2688 for (BasicBlock &BB : F) {
2689 // Stack tracks nested autorelease pools: {push_inst,
2690 // has_autorelease_in_scope}
2691 SmallVector<std::pair<CallInst *, bool>, 4> PoolStack;
2692
2693 for (Instruction &Inst : llvm::make_early_inc_range(Range&: BB)) {
2694 ARCInstKind Class = GetBasicARCInstKind(V: &Inst);
2695
2696 switch (Class) {
2697 case ARCInstKind::AutoreleasepoolPush: {
2698 // Start tracking a new autorelease pool scope
2699 auto *Push = cast<CallInst>(Val: &Inst);
2700 PoolStack.push_back(Elt: {Push, false});
2701 LLVM_DEBUG(dbgs() << "Found autorelease pool push: " << *Push << "\n");
2702 break;
2703 }
2704
2705 case ARCInstKind::AutoreleasepoolPop: {
2706 auto *Pop = cast<CallInst>(Val: &Inst);
2707
2708 // Skip if no matching push found
2709 if (PoolStack.empty())
2710 break;
2711
2712 // Get the matching push and whether autoreleases were present
2713 CallInst *MatchingPush = PoolStack.back().first;
2714 bool HadAutoreleaseInScope = PoolStack.back().second;
2715
2716 // Verify this pop matches the push (handle pointer casts).
2717 // The pop's argument should be the push result, possibly cast.
2718 if (Pop->getArgOperand(i: 0)->stripPointerCasts() != MatchingPush) {
2719 // Mismatched pop.
2720 // We can't trust the stack anymore, invalidating optimization for
2721 // this block.
2722 PoolStack.clear();
2723 LLVM_DEBUG(dbgs() << "Autorelease pool mismatch: pop argument "
2724 << *Pop->getArgOperand(0)
2725 << " does not match most recent push "
2726 << *MatchingPush << "\n");
2727 break;
2728 }
2729
2730 // Pop the stack - remove this pool scope
2731 PoolStack.pop_back();
2732
2733 // Only eliminate pools that had no autoreleases in their scope.
2734 if (HadAutoreleaseInScope)
2735 break;
2736
2737 // Emit the remark before erasing the instructions
2738 ORE.emit(RemarkBuilder: [&]() {
2739 return OptimizationRemark(DEBUG_TYPE, "AutoreleasePoolElimination",
2740 MatchingPush)
2741 << "eliminated empty autorelease pool pair";
2742 });
2743
2744 // Replace all uses of push with poison before deletion, as Pop still
2745 // holds a Use of it.
2746 MatchingPush->replaceAllUsesWith(
2747 V: PoisonValue::get(T: MatchingPush->getType()));
2748
2749 MatchingPush->eraseFromParent();
2750 Pop->eraseFromParent();
2751
2752 Changed = true;
2753 ++NumNoops;
2754 break;
2755 }
2756 case ARCInstKind::CallOrUser:
2757 case ARCInstKind::Call:
2758 // Check if this call might produce autoreleases
2759 if (!MayAutorelease(CB: cast<CallBase>(Val&: Inst)))
2760 break;
2761 [[fallthrough]];
2762 case ARCInstKind::Autorelease:
2763 case ARCInstKind::AutoreleaseRV:
2764 case ARCInstKind::FusedRetainAutorelease:
2765 case ARCInstKind::FusedRetainAutoreleaseRV:
2766 case ARCInstKind::LoadWeak: {
2767 // Mark that we have autorelease operations in the current pool scope
2768 if (!PoolStack.empty()) {
2769 PoolStack.back().second = true;
2770 LLVM_DEBUG(
2771 dbgs()
2772 << "Found autorelease or potential autorelease in pool scope: "
2773 << Inst << "\n");
2774 }
2775 break;
2776 }
2777
2778 // Enumerate all remaining ARCInstKind cases explicitly
2779 case ARCInstKind::Retain:
2780 case ARCInstKind::RetainRV:
2781 case ARCInstKind::UnsafeClaimRV:
2782 case ARCInstKind::RetainBlock:
2783 case ARCInstKind::Release:
2784 case ARCInstKind::NoopCast:
2785 case ARCInstKind::LoadWeakRetained:
2786 case ARCInstKind::StoreWeak:
2787 case ARCInstKind::InitWeak:
2788 case ARCInstKind::MoveWeak:
2789 case ARCInstKind::CopyWeak:
2790 case ARCInstKind::DestroyWeak:
2791 case ARCInstKind::StoreStrong:
2792 case ARCInstKind::IntrinsicUser:
2793 case ARCInstKind::User:
2794 case ARCInstKind::None:
2795 // These instruction kinds don't affect autorelease pool optimization
2796 break;
2797 }
2798 }
2799 }
2800}
2801
2802/// @}
2803///
2804
2805PreservedAnalyses ObjCARCOptPass::run(Function &F,
2806 FunctionAnalysisManager &AM) {
2807 ObjCARCOpt OCAO;
2808 OCAO.init(F);
2809
2810 bool Changed = OCAO.run(F, AA&: AM.getResult<AAManager>(IR&: F));
2811 bool CFGChanged = OCAO.hasCFGChanged();
2812 if (Changed) {
2813 PreservedAnalyses PA;
2814 if (!CFGChanged)
2815 PA.preserveSet<CFGAnalyses>();
2816 return PA;
2817 }
2818 return PreservedAnalyses::all();
2819}
2820