LLVM  13.0.0git
ObjCARCContract.cpp
Go to the documentation of this file.
1 //===- ObjCARCContract.cpp - ObjC ARC Optimization ------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines late ObjC ARC optimizations. ARC stands for Automatic
10 /// Reference Counting and is a system for managing reference counts for objects
11 /// in Objective C.
12 ///
13 /// This specific file mainly deals with ``contracting'' multiple lower level
14 /// operations into singular higher level operations through pattern matching.
15 ///
16 /// WARNING: This file knows about certain library functions. It recognizes them
17 /// by name, and hardwires knowledge of their semantics.
18 ///
19 /// WARNING: This file knows about how certain Objective-C library functions are
20 /// used. Naive LLVM IR transformations which would otherwise be
21 /// behavior-preserving may break these assumptions.
22 ///
23 //===----------------------------------------------------------------------===//
24 
25 // TODO: ObjCARCContract could insert PHI nodes when uses aren't
26 // dominated by single calls.
27 
28 #include "ARCRuntimeEntryPoints.h"
29 #include "DependencyAnalysis.h"
30 #include "ObjCARC.h"
31 #include "ProvenanceAnalysis.h"
32 #include "llvm/ADT/Statistic.h"
36 #include "llvm/IR/Dominators.h"
37 #include "llvm/IR/InlineAsm.h"
38 #include "llvm/IR/InstIterator.h"
39 #include "llvm/IR/Operator.h"
40 #include "llvm/IR/PassManager.h"
41 #include "llvm/InitializePasses.h"
43 #include "llvm/Support/Debug.h"
46 
47 using namespace llvm;
48 using namespace llvm::objcarc;
49 
50 #define DEBUG_TYPE "objc-arc-contract"
51 
52 STATISTIC(NumPeeps, "Number of calls peephole-optimized");
53 STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
54 
55 //===----------------------------------------------------------------------===//
56 // Declarations
57 //===----------------------------------------------------------------------===//
58 
59 namespace {
60 /// Late ARC optimizations
61 ///
62 /// These change the IR in a way that makes it difficult to be analyzed by
63 /// ObjCARCOpt, so it's run late.
64 
65 class ObjCARCContract {
66  bool Changed;
67  bool CFGChanged;
68  AAResults *AA;
69  DominatorTree *DT;
72  BundledRetainClaimRVs *BundledInsts = nullptr;
73 
74  /// The inline asm string to insert between calls and RetainRV calls to make
75  /// the optimization work on targets which need it.
76  const MDString *RVInstMarker;
77 
78  /// The set of inserted objc_storeStrong calls. If at the end of walking the
79  /// function we have found no alloca instructions, these calls can be marked
80  /// "tail".
81  SmallPtrSet<CallInst *, 8> StoreStrongCalls;
82 
83  /// Returns true if we eliminated Inst.
84  bool tryToPeepholeInstruction(
85  Function &F, Instruction *Inst, inst_iterator &Iter,
86  bool &TailOkForStoreStrong,
87  const DenseMap<BasicBlock *, ColorVector> &BlockColors);
88 
89  bool optimizeRetainCall(Function &F, Instruction *Retain);
90 
91  bool contractAutorelease(Function &F, Instruction *Autorelease,
92  ARCInstKind Class);
93 
94  void tryToContractReleaseIntoStoreStrong(
95  Instruction *Release, inst_iterator &Iter,
96  const DenseMap<BasicBlock *, ColorVector> &BlockColors);
97 
98 public:
99  bool init(Module &M);
100  bool run(Function &F, AAResults *AA, DominatorTree *DT);
101  bool hasCFGChanged() const { return CFGChanged; }
102 };
103 
104 class ObjCARCContractLegacyPass : public FunctionPass {
105  ObjCARCContract OCARCC;
106 
107 public:
108  void getAnalysisUsage(AnalysisUsage &AU) const override;
109  bool doInitialization(Module &M) override;
110  bool runOnFunction(Function &F) override;
111 
112  static char ID;
113  ObjCARCContractLegacyPass() : FunctionPass(ID) {
115  }
116 };
117 }
118 
119 //===----------------------------------------------------------------------===//
120 // Implementation
121 //===----------------------------------------------------------------------===//
122 
123 /// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
124 /// return value. We do this late so we do not disrupt the dataflow analysis in
125 /// ObjCARCOpt.
126 bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
127  const auto *Call = dyn_cast<CallBase>(GetArgRCIdentityRoot(Retain));
128  if (!Call)
129  return false;
130  if (Call->getParent() != Retain->getParent())
131  return false;
132 
133  // Check that the call is next to the retain.
134  BasicBlock::const_iterator I = ++Call->getIterator();
135  while (IsNoopInstruction(&*I))
136  ++I;
137  if (&*I != Retain)
138  return false;
139 
140  // Turn it to an objc_retainAutoreleasedReturnValue.
141  Changed = true;
142  ++NumPeeps;
143 
144  LLVM_DEBUG(
145  dbgs() << "Transforming objc_retain => "
146  "objc_retainAutoreleasedReturnValue since the operand is a "
147  "return value.\nOld: "
148  << *Retain << "\n");
149 
150  // We do not have to worry about tail calls/does not throw since
151  // retain/retainRV have the same properties.
153  cast<CallInst>(Retain)->setCalledFunction(Decl);
154 
155  LLVM_DEBUG(dbgs() << "New: " << *Retain << "\n");
156  return true;
157 }
158 
159 /// Merge an autorelease with a retain into a fused call.
160 bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
161  ARCInstKind Class) {
162  const Value *Arg = GetArgRCIdentityRoot(Autorelease);
163 
164  // Check that there are no instructions between the retain and the autorelease
165  // (such as an autorelease_pop) which may change the count.
169  auto *Retain = dyn_cast_or_null<CallInst>(
170  findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));
171 
172  if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
173  GetArgRCIdentityRoot(Retain) != Arg)
174  return false;
175 
176  Changed = true;
177  ++NumPeeps;
178 
179  LLVM_DEBUG(dbgs() << " Fusing retain/autorelease!\n"
180  " Autorelease:"
181  << *Autorelease
182  << "\n"
183  " Retain: "
184  << *Retain << "\n");
185 
186  Function *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
189  Retain->setCalledFunction(Decl);
190 
191  LLVM_DEBUG(dbgs() << " New RetainAutorelease: " << *Retain << "\n");
192 
193  EraseInstruction(Autorelease);
194  return true;
195 }
196 
198  Instruction *Release,
199  ProvenanceAnalysis &PA,
200  AAResults *AA) {
201  StoreInst *Store = nullptr;
202  bool SawRelease = false;
203 
204  // Get the location associated with Load.
206  auto *LocPtr = Loc.Ptr->stripPointerCasts();
207 
208  // Walk down to find the store and the release, which may be in either order.
209  for (auto I = std::next(BasicBlock::iterator(Load)),
210  E = Load->getParent()->end();
211  I != E; ++I) {
212  // If we found the store we were looking for and saw the release,
213  // break. There is no more work to be done.
214  if (Store && SawRelease)
215  break;
216 
217  // Now we know that we have not seen either the store or the release. If I
218  // is the release, mark that we saw the release and continue.
219  Instruction *Inst = &*I;
220  if (Inst == Release) {
221  SawRelease = true;
222  continue;
223  }
224 
225  // Otherwise, we check if Inst is a "good" store. Grab the instruction class
226  // of Inst.
227  ARCInstKind Class = GetBasicARCInstKind(Inst);
228 
229  // If Inst is an unrelated retain, we don't care about it.
230  //
231  // TODO: This is one area where the optimization could be made more
232  // aggressive.
233  if (IsRetain(Class))
234  continue;
235 
236  // If we have seen the store, but not the release...
237  if (Store) {
238  // We need to make sure that it is safe to move the release from its
239  // current position to the store. This implies proving that any
240  // instruction in between Store and the Release conservatively can not use
241  // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
242  // continue...
243  if (!CanUse(Inst, Load, PA, Class)) {
244  continue;
245  }
246 
247  // Otherwise, be conservative and return nullptr.
248  return nullptr;
249  }
250 
251  // Ok, now we know we have not seen a store yet. See if Inst can write to
252  // our load location, if it can not, just ignore the instruction.
253  if (!isModSet(AA->getModRefInfo(Inst, Loc)))
254  continue;
255 
256  Store = dyn_cast<StoreInst>(Inst);
257 
258  // If Inst can, then check if Inst is a simple store. If Inst is not a
259  // store or a store that is not simple, then we have some we do not
260  // understand writing to this memory implying we can not move the load
261  // over the write to any subsequent store that we may find.
262  if (!Store || !Store->isSimple())
263  return nullptr;
264 
265  // Then make sure that the pointer we are storing to is Ptr. If so, we
266  // found our Store!
267  if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
268  continue;
269 
270  // Otherwise, we have an unknown store to some other ptr that clobbers
271  // Loc.Ptr. Bail!
272  return nullptr;
273  }
274 
275  // If we did not find the store or did not see the release, fail.
276  if (!Store || !SawRelease)
277  return nullptr;
278 
279  // We succeeded!
280  return Store;
281 }
282 
283 static Instruction *
285  Instruction *Release,
286  ProvenanceAnalysis &PA) {
287  // Walk up from the Store to find the retain.
288  BasicBlock::iterator I = Store->getIterator();
289  BasicBlock::iterator Begin = Store->getParent()->begin();
290  while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
291  Instruction *Inst = &*I;
292 
293  // It is only safe to move the retain to the store if we can prove
294  // conservatively that nothing besides the release can decrement reference
295  // counts in between the retain and the store.
296  if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
297  return nullptr;
298  --I;
299  }
300  Instruction *Retain = &*I;
302  return nullptr;
303  if (GetArgRCIdentityRoot(Retain) != New)
304  return nullptr;
305  return Retain;
306 }
307 
308 /// Attempt to merge an objc_release with a store, load, and objc_retain to form
309 /// an objc_storeStrong. An objc_storeStrong:
310 ///
311 /// objc_storeStrong(i8** %old_ptr, i8* new_value)
312 ///
313 /// is equivalent to the following IR sequence:
314 ///
315 /// ; Load old value.
316 /// %old_value = load i8** %old_ptr (1)
317 ///
318 /// ; Increment the new value and then release the old value. This must occur
319 /// ; in order in case old_value releases new_value in its destructor causing
320 /// ; us to potentially have a dangling ptr.
321 /// tail call i8* @objc_retain(i8* %new_value) (2)
322 /// tail call void @objc_release(i8* %old_value) (3)
323 ///
324 /// ; Store the new_value into old_ptr
325 /// store i8* %new_value, i8** %old_ptr (4)
326 ///
327 /// The safety of this optimization is based around the following
328 /// considerations:
329 ///
330 /// 1. We are forming the store strong at the store. Thus to perform this
331 /// optimization it must be safe to move the retain, load, and release to
332 /// (4).
333 /// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
334 /// safe.
335 void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
336  Instruction *Release, inst_iterator &Iter,
337  const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
338  // See if we are releasing something that we just loaded.
339  auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
340  if (!Load || !Load->isSimple())
341  return;
342 
343  // For now, require everything to be in one basic block.
344  BasicBlock *BB = Release->getParent();
345  if (Load->getParent() != BB)
346  return;
347 
348  // First scan down the BB from Load, looking for a store of the RCIdentityRoot
349  // of Load's
350  StoreInst *Store =
352  // If we fail, bail.
353  if (!Store)
354  return;
355 
356  // Then find what new_value's RCIdentity Root is.
357  Value *New = GetRCIdentityRoot(Store->getValueOperand());
358 
359  // Then walk up the BB and look for a retain on New without any intervening
360  // instructions which conservatively might decrement ref counts.
362  findRetainForStoreStrongContraction(New, Store, Release, PA);
363 
364  // If we fail, bail.
365  if (!Retain)
366  return;
367 
368  Changed = true;
369  ++NumStoreStrongs;
370 
371  LLVM_DEBUG(
372  llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n"
373  << " Old:\n"
374  << " Store: " << *Store << "\n"
375  << " Release: " << *Release << "\n"
376  << " Retain: " << *Retain << "\n"
377  << " Load: " << *Load << "\n");
378 
379  LLVMContext &C = Release->getContext();
381  Type *I8XX = PointerType::getUnqual(I8X);
382 
383  Value *Args[] = { Load->getPointerOperand(), New };
384  if (Args[0]->getType() != I8XX)
385  Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
386  if (Args[1]->getType() != I8X)
387  Args[1] = new BitCastInst(Args[1], I8X, "", Store);
390  objcarc::createCallInstWithColors(Decl, Args, "", Store, BlockColors);
391  StoreStrong->setDoesNotThrow();
392  StoreStrong->setDebugLoc(Store->getDebugLoc());
393 
394  // We can't set the tail flag yet, because we haven't yet determined
395  // whether there are any escaping allocas. Remember this call, so that
396  // we can set the tail flag once we know it's safe.
397  StoreStrongCalls.insert(StoreStrong);
398 
399  LLVM_DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong
400  << "\n");
401 
402  if (&*Iter == Retain) ++Iter;
403  if (&*Iter == Store) ++Iter;
404  Store->eraseFromParent();
405  Release->eraseFromParent();
406  EraseInstruction(Retain);
407  if (Load->use_empty())
408  Load->eraseFromParent();
409 }
410 
411 bool ObjCARCContract::tryToPeepholeInstruction(
412  Function &F, Instruction *Inst, inst_iterator &Iter,
413  bool &TailOkForStoreStrongs,
414  const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
415  // Only these library routines return their argument. In particular,
416  // objc_retainBlock does not necessarily return its argument.
418  switch (Class) {
421  return false;
424  return contractAutorelease(F, Inst, Class);
425  case ARCInstKind::Retain:
426  // Attempt to convert retains to retainrvs if they are next to function
427  // calls.
428  if (!optimizeRetainCall(F, Inst))
429  return false;
430  // If we succeed in our optimization, fall through.
433  case ARCInstKind::ClaimRV: {
434  // If we're compiling for a target which needs a special inline-asm
435  // marker to do the return value optimization and the retainRV/claimRV call
436  // wasn't bundled with a call, insert the marker now.
437  if (!RVInstMarker)
438  return false;
439 
440  if (BundledInsts->contains(Inst))
441  return false;
442 
443  BasicBlock::iterator BBI = Inst->getIterator();
444  BasicBlock *InstParent = Inst->getParent();
445 
446  // Step up to see if the call immediately precedes the RV call.
447  // If it's an invoke, we have to cross a block boundary. And we have
448  // to carefully dodge no-op instructions.
449  do {
450  if (BBI == InstParent->begin()) {
451  BasicBlock *Pred = InstParent->getSinglePredecessor();
452  if (!Pred)
453  goto decline_rv_optimization;
454  BBI = Pred->getTerminator()->getIterator();
455  break;
456  }
457  --BBI;
458  } while (IsNoopInstruction(&*BBI));
459 
460  if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
461  LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
462  "optimization.\n");
463  Changed = true;
464  InlineAsm *IA =
466  /*isVarArg=*/false),
467  RVInstMarker->getString(),
468  /*Constraints=*/"", /*hasSideEffects=*/true);
469 
470  objcarc::createCallInstWithColors(IA, None, "", Inst, BlockColors);
471  }
472  decline_rv_optimization:
473  return false;
474  }
475  case ARCInstKind::InitWeak: {
476  // objc_initWeak(p, null) => *p = null
477  CallInst *CI = cast<CallInst>(Inst);
478  if (IsNullOrUndef(CI->getArgOperand(1))) {
479  Value *Null = ConstantPointerNull::get(cast<PointerType>(CI->getType()));
480  Changed = true;
481  new StoreInst(Null, CI->getArgOperand(0), CI);
482 
483  LLVM_DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
484  << " New = " << *Null << "\n");
485 
486  CI->replaceAllUsesWith(Null);
487  CI->eraseFromParent();
488  }
489  return true;
490  }
492  // Try to form an objc store strong from our release. If we fail, there is
493  // nothing further to do below, so continue.
494  tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
495  return true;
496  case ARCInstKind::User:
497  // Be conservative if the function has any alloca instructions.
498  // Technically we only care about escaping alloca instructions,
499  // but this is sufficient to handle some interesting cases.
500  if (isa<AllocaInst>(Inst))
501  TailOkForStoreStrongs = false;
502  return true;
504  // Remove calls to @llvm.objc.clang.arc.use(...).
505  Changed = true;
506  Inst->eraseFromParent();
507  return true;
508  default:
509  if (auto *CI = dyn_cast<CallInst>(Inst))
510  if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
511  // Remove calls to @llvm.objc.clang.arc.noop.use(...).
512  Changed = true;
513  CI->eraseFromParent();
514  }
515  return true;
516  }
517 }
518 
519 //===----------------------------------------------------------------------===//
520 // Top Level Driver
521 //===----------------------------------------------------------------------===//
522 
523 bool ObjCARCContract::init(Module &M) {
524  EP.init(&M);
525 
526  // Initialize RVInstMarker.
527  RVInstMarker = getRVInstMarker(M);
528 
529  return false;
530 }
531 
532 bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
533  if (!EnableARCOpts)
534  return false;
535 
536  Changed = CFGChanged = false;
537  AA = A;
538  DT = D;
539  PA.setAA(A);
540  BundledRetainClaimRVs BRV(EP, true);
541  BundledInsts = &BRV;
542 
543  std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
544  Changed |= R.first;
545  CFGChanged |= R.second;
546 
548  if (F.hasPersonalityFn() &&
549  isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
550  BlockColors = colorEHFunclets(F);
551 
552  LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
553 
554  // Track whether it's ok to mark objc_storeStrong calls with the "tail"
555  // keyword. Be conservative if the function has variadic arguments.
556  // It seems that functions which "return twice" are also unsafe for the
557  // "tail" argument, because they are setjmp, which could need to
558  // return to an earlier stack state.
559  bool TailOkForStoreStrongs =
560  !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
561 
562  // For ObjC library calls which return their argument, replace uses of the
563  // argument with uses of the call return value, if it dominates the use. This
564  // reduces register pressure.
565  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
566  Instruction *Inst = &*I++;
567 
568  LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
569 
570  if (auto *CI = dyn_cast<CallInst>(Inst))
572  BundledInsts->insertRVCallWithColors(&*I, CI, BlockColors);
573  --I;
574  Changed = true;
575  }
576 
577  // First try to peephole Inst. If there is nothing further we can do in
578  // terms of undoing objc-arc-expand, process the next inst.
579  if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
580  BlockColors))
581  continue;
582 
583  // Otherwise, try to undo objc-arc-expand.
584 
585  // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
586  // and such; to do the replacement, the argument must have type i8*.
587 
588  // Function for replacing uses of Arg dominated by Inst.
589  auto ReplaceArgUses = [Inst, this](Value *Arg) {
590  // If we're compiling bugpointed code, don't get in trouble.
591  if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
592  return;
593 
594  // Look through the uses of the pointer.
595  for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
596  UI != UE; ) {
597  // Increment UI now, because we may unlink its element.
598  Use &U = *UI++;
599  unsigned OperandNo = U.getOperandNo();
600 
601  // If the call's return value dominates a use of the call's argument
602  // value, rewrite the use to use the return value. We check for
603  // reachability here because an unreachable call is considered to
604  // trivially dominate itself, which would lead us to rewriting its
605  // argument in terms of its return value, which would lead to
606  // infinite loops in GetArgRCIdentityRoot.
607  if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
608  continue;
609 
610  Changed = true;
611  Instruction *Replacement = Inst;
612  Type *UseTy = U.get()->getType();
613  if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
614  // For PHI nodes, insert the bitcast in the predecessor block.
615  unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
616  BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
617  if (Replacement->getType() != UseTy) {
618  // A catchswitch is both a pad and a terminator, meaning a basic
619  // block with a catchswitch has no insertion point. Keep going up
620  // the dominator tree until we find a non-catchswitch.
621  BasicBlock *InsertBB = IncomingBB;
622  while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) {
623  InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
624  }
625 
626  assert(DT->dominates(Inst, &InsertBB->back()) &&
627  "Invalid insertion point for bitcast");
628  Replacement =
629  new BitCastInst(Replacement, UseTy, "", &InsertBB->back());
630  }
631 
632  // While we're here, rewrite all edges for this PHI, rather
633  // than just one use at a time, to minimize the number of
634  // bitcasts we emit.
635  for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
636  if (PHI->getIncomingBlock(i) == IncomingBB) {
637  // Keep the UI iterator valid.
638  if (UI != UE &&
639  &PHI->getOperandUse(
641  ++UI;
642  PHI->setIncomingValue(i, Replacement);
643  }
644  } else {
645  if (Replacement->getType() != UseTy)
646  Replacement = new BitCastInst(Replacement, UseTy, "",
647  cast<Instruction>(U.getUser()));
648  U.set(Replacement);
649  }
650  }
651  };
652 
653  Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
654  Value *OrigArg = Arg;
655 
656  // TODO: Change this to a do-while.
657  for (;;) {
658  ReplaceArgUses(Arg);
659 
660  // If Arg is a no-op casted pointer, strip one level of casts and iterate.
661  if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
662  Arg = BI->getOperand(0);
663  else if (isa<GEPOperator>(Arg) &&
664  cast<GEPOperator>(Arg)->hasAllZeroIndices())
665  Arg = cast<GEPOperator>(Arg)->getPointerOperand();
666  else if (isa<GlobalAlias>(Arg) &&
667  !cast<GlobalAlias>(Arg)->isInterposable())
668  Arg = cast<GlobalAlias>(Arg)->getAliasee();
669  else {
670  // If Arg is a PHI node, get PHIs that are equivalent to it and replace
671  // their uses.
672  if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
673  SmallVector<Value *, 1> PHIList;
674  getEquivalentPHIs(*PN, PHIList);
675  for (Value *PHI : PHIList)
676  ReplaceArgUses(PHI);
677  }
678  break;
679  }
680  }
681 
682  // Replace bitcast users of Arg that are dominated by Inst.
683  SmallVector<BitCastInst *, 2> BitCastUsers;
684 
685  // Add all bitcast users of the function argument first.
686  for (User *U : OrigArg->users())
687  if (auto *BC = dyn_cast<BitCastInst>(U))
688  BitCastUsers.push_back(BC);
689 
690  // Replace the bitcasts with the call return. Iterate until list is empty.
691  while (!BitCastUsers.empty()) {
692  auto *BC = BitCastUsers.pop_back_val();
693  for (User *U : BC->users())
694  if (auto *B = dyn_cast<BitCastInst>(U))
695  BitCastUsers.push_back(B);
696 
697  ReplaceArgUses(BC);
698  }
699  }
700 
701  // If this function has no escaping allocas or suspicious vararg usage,
702  // objc_storeStrong calls can be marked with the "tail" keyword.
703  if (TailOkForStoreStrongs)
704  for (CallInst *CI : StoreStrongCalls)
705  CI->setTailCall();
706  StoreStrongCalls.clear();
707 
708  return Changed;
709 }
710 
711 //===----------------------------------------------------------------------===//
712 // Misc Pass Manager
713 //===----------------------------------------------------------------------===//
714 
716 INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
717  "ObjC ARC contraction", false, false)
720 INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
721  "ObjC ARC contraction", false, false)
722 
723 void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
724  AU.addRequired<AAResultsWrapperPass>();
725  AU.addRequired<DominatorTreeWrapperPass>();
726 }
727 
729  return new ObjCARCContractLegacyPass();
730 }
731 
732 bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
733  return OCARCC.init(M);
734 }
735 
737  auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
738  auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
739  return OCARCC.run(F, AA, DT);
740 }
741 
744  ObjCARCContract OCAC;
745  OCAC.init(*F.getParent());
746 
747  bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
749  bool CFGChanged = OCAC.hasCFGChanged();
750  if (Changed) {
752  if (!CFGChanged)
753  PA.preserveSet<CFGAnalyses>();
754  return PA;
755  }
756  return PreservedAnalyses::all();
757 }
llvm::objcarc::BundledRetainClaimRVs
Definition: ObjCARC.h:106
llvm::objcarc::GetBasicARCInstKind
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
Definition: ObjCARCInstKind.h:104
i
i
Definition: README.txt:29
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm::objcarc::ARCInstKind::User
@ User
could "use" a pointer
llvm::AAManager
A manager for alias analyses.
Definition: AliasAnalysis.h:1233
llvm::objcarc::CanUse
bool CanUse(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Test whether the given instruction can "use" the given pointer's object in a way that requires the re...
Definition: DependencyAnalysis.cpp:80
llvm::MemoryLocation::get
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Definition: MemoryLocation.cpp:37
llvm
Definition: AllocatorList.h:23
llvm::objcarc::ARCRuntimeEntryPointKind::RetainAutoreleaseRV
@ RetainAutoreleaseRV
llvm::objcarc::ARCRuntimeEntryPointKind::StoreStrong
@ StoreStrong
llvm::CallInst::setTailCall
void setTailCall(bool IsTc=true)
Definition: Instructions.h:1685
contract
objc arc contract
Definition: ObjCARCContract.cpp:720
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:90
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:769
llvm::MemoryLocation::Ptr
const Value * Ptr
The address of the start of the location.
Definition: MemoryLocation.h:217
InstIterator.h
llvm::Function
Definition: Function.h:61
arc
objc arc
Definition: ObjCARCOpts.cpp:607
llvm::BitCastInst
This class represents a no-op cast from one type to another.
Definition: Instructions.h:5166
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1167
Statistic.h
InlineAsm.h
llvm::PHINode::getOperandNumForIncomingValue
static unsigned getOperandNumForIncomingValue(unsigned i)
Definition: Instructions.h:2706
llvm::Use::get
Value * get() const
Definition: Use.h:67
llvm::objcarc::RetainAutoreleaseDep
@ RetainAutoreleaseDep
Blocks objc_retainAutorelease.
Definition: DependencyAnalysis.h:48
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:321
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:151
llvm::objcarc::ARCRuntimeEntryPointKind::RetainRV
@ RetainRV
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
EHPersonalities.h
llvm::Use::getOperandNo
unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition: Use.cpp:33
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:449
Operator.h
llvm::BasicBlock::getSinglePredecessor
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
Definition: BasicBlock.cpp:264
llvm::objcarc::ProvenanceAnalysis
This is similar to BasicAliasAnalysis, and it uses many of the same techniques, except it uses specia...
Definition: ProvenanceAnalysis.h:51
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:634
findSafeStoreForStoreStrongContraction
static StoreInst * findSafeStoreForStoreStrongContraction(LoadInst *Load, Instruction *Release, ProvenanceAnalysis &PA, AAResults *AA)
Definition: ObjCARCContract.cpp:197
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:195
llvm::objcarc::ARCInstKind::Autorelease
@ Autorelease
objc_autorelease
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:180
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
AliasAnalysis.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
CommandLine.h
llvm::Intrinsic::getType
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Definition: Function.cpp:1285
llvm::pdb::PDB_LocType::Null
@ Null
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::initializeObjCARCContractLegacyPassPass
void initializeObjCARCContractLegacyPassPass(PassRegistry &)
llvm::Value::use_iterator
use_iterator_impl< Use > use_iterator
Definition: Value.h:354
llvm::AAResults
Definition: AliasAnalysis.h:456
llvm::objcarc::ARCInstKind::InitWeak
@ InitWeak
objc_initWeak (derived)
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::objcarc::GetArgRCIdentityRoot
Value * GetArgRCIdentityRoot(Value *Inst)
Assuming the given instruction is one of the special calls such as objc_retain or objc_release,...
Definition: ObjCARCAnalysisUtils.h:128
llvm::User
Definition: User.h:44
DependencyAnalysis.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
findRetainForStoreStrongContraction
static Instruction * findRetainForStoreStrongContraction(Value *New, StoreInst *Store, Instruction *Release, ProvenanceAnalysis &PA)
Definition: ObjCARCContract.cpp:284
llvm::BasicBlock::begin
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:296
llvm::objcarc::hasAttachedCallOpBundle
bool hasAttachedCallOpBundle(const CallBase *CB, bool IsRetain)
Definition: ObjCARCUtil.h:34
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::objcarc::ARCInstKind::Release
@ Release
objc_release
llvm::objcarc::ARCInstKind::RetainRV
@ RetainRV
objc_retainAutoreleasedReturnValue
false
Definition: StackSlotColoring.cpp:142
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::objcarc::getEquivalentPHIs
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList)
Return the list of PHI nodes that are equivalent to PN.
Definition: ObjCARC.h:75
llvm::Instruction
Definition: Instruction.h:45
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:281
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::objcarc::ARCInstKind::IntrinsicUser
@ IntrinsicUser
llvm.objc.clang.arc.use
llvm::Use::getUser
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:73
llvm::objcarc::DependenceKind
DependenceKind
Definition: DependencyAnalysis.h:44
llvm::BasicBlock::getFirstNonPHI
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Definition: BasicBlock.cpp:212
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:153
llvm::isModSet
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
Definition: AliasAnalysis.h:196
llvm::InlineAsm::get
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:42
llvm::objcarc::ARCInstKind
ARCInstKind
Definition: ObjCARCInstKind.h:28
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
ARCRuntimeEntryPoints.h
llvm::PHINode::getIncomingValueNumForOperand
static unsigned getIncomingValueNumForOperand(unsigned i)
Definition: Instructions.h:2710
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::Use::set
void set(Value *Val)
Definition: Value.h:860
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:303
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:78
ProvenanceAnalysis.h
llvm::PointerType::getUnqual
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:653
llvm::colorEHFunclets
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
Definition: EHPersonalities.cpp:81
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::objcarc::ARCInstKind::FusedRetainAutorelease
@ FusedRetainAutorelease
objc_retainAutorelease
llvm::ConstantPointerNull::get
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1769
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::isScopedEHPersonality
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
Definition: EHPersonalities.h:80
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract", "ObjC ARC contraction", false, false) INITIALIZE_PASS_END(ObjCARCContractLegacyPass
llvm::objcarc::EnableARCOpts
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
Definition: ObjCARCAnalysisUtils.cpp:23
llvm::objcarc::IsRetain
bool IsRetain(ARCInstKind Class)
Test if the given class is objc_retain or equivalent.
Definition: ObjCARCInstKind.cpp:345
llvm::objcarc
Definition: ObjCARCAliasAnalysis.h:29
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::objcarc::ARCRuntimeEntryPointKind::RetainAutorelease
@ RetainAutorelease
llvm::objcarc::IsNoopInstruction
bool IsNoopInstruction(const Instruction *I)
Definition: ObjCARCAnalysisUtils.h:136
llvm::objcarc::RetainAutoreleaseRVDep
@ RetainAutoreleaseRVDep
Blocks objc_retainAutoreleaseReturnValue.
Definition: DependencyAnalysis.h:49
llvm::CallBase::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
Definition: Instructions.cpp:307
llvm::objcarc::IsNullOrUndef
bool IsNullOrUndef(const Value *V)
Definition: ObjCARCAnalysisUtils.h:132
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
llvm::ObjCARCContractPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: ObjCARCContract.cpp:742
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:116
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:517
llvm::ms_demangle::IntrinsicFunctionKind::New
@ New
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:965
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:81
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:281
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::BasicBlock::getTerminator
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:148
llvm::objcarc::GetRCIdentityRoot
const Value * GetRCIdentityRoot(const Value *V)
The RCIdentity root of a value V is a dominating value U for which retaining or releasing U is equiva...
Definition: ObjCARCAnalysisUtils.h:107
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:662
ObjCARCUtil.h
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::objcarc::ARCRuntimeEntryPoints
Declarations for ObjC runtime functions and constants.
Definition: ARCRuntimeEntryPoints.h:52
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
llvm::objcarc::getRVInstMarker
static MDString * getRVInstMarker(Module &M)
Definition: ObjCARC.h:93
llvm::objcarc::ARCInstKind::FusedRetainAutoreleaseRV
@ FusedRetainAutoreleaseRV
objc_retainAutoreleaseReturnValue
llvm::inst_end
inst_iterator inst_end(Function *F)
Definition: InstIterator.h:132
contraction
objc arc ObjC ARC contraction
Definition: ObjCARCContract.cpp:721
PassManager.h
llvm::objcarc::findSingleDependency
llvm::Instruction * findSingleDependency(DependenceKind Flavor, const Value *Arg, BasicBlock *StartBB, Instruction *StartInst, ProvenanceAnalysis &PA)
Find dependent instructions.
Definition: DependencyAnalysis.cpp:263
llvm::objcarc::ARCInstKind::StoreStrong
@ StoreStrong
objc_storeStrong (derived)
llvm::objcarc::CanDecrementRefCount
bool CanDecrementRefCount(ARCInstKind Kind)
Returns false if conservatively we can prove that any instruction mapped to this kind can not decreme...
Definition: ObjCARCInstKind.cpp:668
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::objcarc::EraseInstruction
static void EraseInstruction(Instruction *CI)
Erase the given instruction.
Definition: ObjCARC.h:40
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
llvm::BasicBlock::back
const Instruction & back() const
Definition: BasicBlock.h:310
llvm::objcarc::ARCInstKind::ClaimRV
@ ClaimRV
objc_unsafeClaimAutoreleasedReturnValue
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:252
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:180
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
llvm::PreservedAnalyses::preserveSet
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:191
ObjCARC.h
Dominators.h
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1341
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition: AliasAnalysis.h:1281
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
llvm::objcarc::createCallInstWithColors
CallInst * createCallInstWithColors(FunctionCallee Func, ArrayRef< Value * > Args, const Twine &NameStr, Instruction *InsertBefore, const DenseMap< BasicBlock *, ColorVector > &BlockColors)
Create a call instruction with the correct funclet token.
Definition: ObjCARC.cpp:46
llvm::PHINode
Definition: Instructions.h:2600
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1478
llvm::InliningAdvisorMode::Release
@ Release
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::inst_begin
inst_iterator inst_begin(Function *F)
Definition: InstIterator.h:131
llvm::createObjCARCContractPass
Pass * createObjCARCContractPass()
Definition: ObjCARCContract.cpp:728
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::InstIterator
Definition: InstIterator.h:32
raw_ostream.h
llvm::MDString
A single uniqued string.
Definition: Metadata.h:611
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::objcarc::ARCInstKind::Retain
@ Retain
objc_retain
Debug.h
llvm::Value::users
iterator_range< user_iterator > users()
Definition: Value.h:422
llvm::AAResults::getModRefInfo
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
Definition: AliasAnalysis.cpp:219
llvm::MemoryLocation
Representation for a specific memory location.
Definition: MemoryLocation.h:209
llvm::BasicBlock::const_iterator
InstListType::const_iterator const_iterator
Definition: BasicBlock.h:91
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::objcarc::ARCInstKind::AutoreleaseRV
@ AutoreleaseRV
objc_autoreleaseReturnValue
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38