LLVM  14.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 we have seen the store, but not the release...
230  if (Store) {
231  // We need to make sure that it is safe to move the release from its
232  // current position to the store. This implies proving that any
233  // instruction in between Store and the Release conservatively can not use
234  // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
235  // continue...
236  if (!CanUse(Inst, Load, PA, Class)) {
237  continue;
238  }
239 
240  // Otherwise, be conservative and return nullptr.
241  return nullptr;
242  }
243 
244  // Ok, now we know we have not seen a store yet.
245 
246  // If Inst is a retain, we don't care about it as it doesn't prevent moving
247  // the load to the store.
248  //
249  // TODO: This is one area where the optimization could be made more
250  // aggressive.
251  if (IsRetain(Class))
252  continue;
253 
254  // See if Inst can write to our load location, if it can not, just ignore
255  // the instruction.
256  if (!isModSet(AA->getModRefInfo(Inst, Loc)))
257  continue;
258 
259  Store = dyn_cast<StoreInst>(Inst);
260 
261  // If Inst can, then check if Inst is a simple store. If Inst is not a
262  // store or a store that is not simple, then we have some we do not
263  // understand writing to this memory implying we can not move the load
264  // over the write to any subsequent store that we may find.
265  if (!Store || !Store->isSimple())
266  return nullptr;
267 
268  // Then make sure that the pointer we are storing to is Ptr. If so, we
269  // found our Store!
270  if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
271  continue;
272 
273  // Otherwise, we have an unknown store to some other ptr that clobbers
274  // Loc.Ptr. Bail!
275  return nullptr;
276  }
277 
278  // If we did not find the store or did not see the release, fail.
279  if (!Store || !SawRelease)
280  return nullptr;
281 
282  // We succeeded!
283  return Store;
284 }
285 
286 static Instruction *
288  Instruction *Release,
289  ProvenanceAnalysis &PA) {
290  // Walk up from the Store to find the retain.
291  BasicBlock::iterator I = Store->getIterator();
292  BasicBlock::iterator Begin = Store->getParent()->begin();
293  while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
294  Instruction *Inst = &*I;
295 
296  // It is only safe to move the retain to the store if we can prove
297  // conservatively that nothing besides the release can decrement reference
298  // counts in between the retain and the store.
299  if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
300  return nullptr;
301  --I;
302  }
303  Instruction *Retain = &*I;
305  return nullptr;
306  if (GetArgRCIdentityRoot(Retain) != New)
307  return nullptr;
308  return Retain;
309 }
310 
311 /// Attempt to merge an objc_release with a store, load, and objc_retain to form
312 /// an objc_storeStrong. An objc_storeStrong:
313 ///
314 /// objc_storeStrong(i8** %old_ptr, i8* new_value)
315 ///
316 /// is equivalent to the following IR sequence:
317 ///
318 /// ; Load old value.
319 /// %old_value = load i8** %old_ptr (1)
320 ///
321 /// ; Increment the new value and then release the old value. This must occur
322 /// ; in order in case old_value releases new_value in its destructor causing
323 /// ; us to potentially have a dangling ptr.
324 /// tail call i8* @objc_retain(i8* %new_value) (2)
325 /// tail call void @objc_release(i8* %old_value) (3)
326 ///
327 /// ; Store the new_value into old_ptr
328 /// store i8* %new_value, i8** %old_ptr (4)
329 ///
330 /// The safety of this optimization is based around the following
331 /// considerations:
332 ///
333 /// 1. We are forming the store strong at the store. Thus to perform this
334 /// optimization it must be safe to move the retain, load, and release to
335 /// (4).
336 /// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
337 /// safe.
338 void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
339  Instruction *Release, inst_iterator &Iter,
340  const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
341  // See if we are releasing something that we just loaded.
342  auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
343  if (!Load || !Load->isSimple())
344  return;
345 
346  // For now, require everything to be in one basic block.
347  BasicBlock *BB = Release->getParent();
348  if (Load->getParent() != BB)
349  return;
350 
351  // First scan down the BB from Load, looking for a store of the RCIdentityRoot
352  // of Load's
353  StoreInst *Store =
355  // If we fail, bail.
356  if (!Store)
357  return;
358 
359  // Then find what new_value's RCIdentity Root is.
360  Value *New = GetRCIdentityRoot(Store->getValueOperand());
361 
362  // Then walk up the BB and look for a retain on New without any intervening
363  // instructions which conservatively might decrement ref counts.
365  findRetainForStoreStrongContraction(New, Store, Release, PA);
366 
367  // If we fail, bail.
368  if (!Retain)
369  return;
370 
371  Changed = true;
372  ++NumStoreStrongs;
373 
374  LLVM_DEBUG(
375  llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n"
376  << " Old:\n"
377  << " Store: " << *Store << "\n"
378  << " Release: " << *Release << "\n"
379  << " Retain: " << *Retain << "\n"
380  << " Load: " << *Load << "\n");
381 
382  LLVMContext &C = Release->getContext();
384  Type *I8XX = PointerType::getUnqual(I8X);
385 
386  Value *Args[] = { Load->getPointerOperand(), New };
387  if (Args[0]->getType() != I8XX)
388  Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
389  if (Args[1]->getType() != I8X)
390  Args[1] = new BitCastInst(Args[1], I8X, "", Store);
393  objcarc::createCallInstWithColors(Decl, Args, "", Store, BlockColors);
394  StoreStrong->setDoesNotThrow();
395  StoreStrong->setDebugLoc(Store->getDebugLoc());
396 
397  // We can't set the tail flag yet, because we haven't yet determined
398  // whether there are any escaping allocas. Remember this call, so that
399  // we can set the tail flag once we know it's safe.
400  StoreStrongCalls.insert(StoreStrong);
401 
402  LLVM_DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong
403  << "\n");
404 
405  if (&*Iter == Retain) ++Iter;
406  if (&*Iter == Store) ++Iter;
407  Store->eraseFromParent();
408  Release->eraseFromParent();
409  EraseInstruction(Retain);
410  if (Load->use_empty())
411  Load->eraseFromParent();
412 }
413 
414 bool ObjCARCContract::tryToPeepholeInstruction(
415  Function &F, Instruction *Inst, inst_iterator &Iter,
416  bool &TailOkForStoreStrongs,
417  const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
418  // Only these library routines return their argument. In particular,
419  // objc_retainBlock does not necessarily return its argument.
421  switch (Class) {
424  return false;
427  return contractAutorelease(F, Inst, Class);
428  case ARCInstKind::Retain:
429  // Attempt to convert retains to retainrvs if they are next to function
430  // calls.
431  if (!optimizeRetainCall(F, Inst))
432  return false;
433  // If we succeed in our optimization, fall through.
436  case ARCInstKind::ClaimRV: {
437  // If we're compiling for a target which needs a special inline-asm
438  // marker to do the return value optimization and the retainRV/claimRV call
439  // wasn't bundled with a call, insert the marker now.
440  if (!RVInstMarker)
441  return false;
442 
443  if (BundledInsts->contains(Inst))
444  return false;
445 
446  BasicBlock::iterator BBI = Inst->getIterator();
447  BasicBlock *InstParent = Inst->getParent();
448 
449  // Step up to see if the call immediately precedes the RV call.
450  // If it's an invoke, we have to cross a block boundary. And we have
451  // to carefully dodge no-op instructions.
452  do {
453  if (BBI == InstParent->begin()) {
454  BasicBlock *Pred = InstParent->getSinglePredecessor();
455  if (!Pred)
456  goto decline_rv_optimization;
457  BBI = Pred->getTerminator()->getIterator();
458  break;
459  }
460  --BBI;
461  } while (IsNoopInstruction(&*BBI));
462 
463  if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
464  LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
465  "optimization.\n");
466  Changed = true;
467  InlineAsm *IA =
469  /*isVarArg=*/false),
470  RVInstMarker->getString(),
471  /*Constraints=*/"", /*hasSideEffects=*/true);
472 
473  objcarc::createCallInstWithColors(IA, None, "", Inst, BlockColors);
474  }
475  decline_rv_optimization:
476  return false;
477  }
478  case ARCInstKind::InitWeak: {
479  // objc_initWeak(p, null) => *p = null
480  CallInst *CI = cast<CallInst>(Inst);
481  if (IsNullOrUndef(CI->getArgOperand(1))) {
482  Value *Null = ConstantPointerNull::get(cast<PointerType>(CI->getType()));
483  Changed = true;
484  new StoreInst(Null, CI->getArgOperand(0), CI);
485 
486  LLVM_DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
487  << " New = " << *Null << "\n");
488 
489  CI->replaceAllUsesWith(Null);
490  CI->eraseFromParent();
491  }
492  return true;
493  }
495  // Try to form an objc store strong from our release. If we fail, there is
496  // nothing further to do below, so continue.
497  tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
498  return true;
499  case ARCInstKind::User:
500  // Be conservative if the function has any alloca instructions.
501  // Technically we only care about escaping alloca instructions,
502  // but this is sufficient to handle some interesting cases.
503  if (isa<AllocaInst>(Inst))
504  TailOkForStoreStrongs = false;
505  return true;
507  // Remove calls to @llvm.objc.clang.arc.use(...).
508  Changed = true;
509  Inst->eraseFromParent();
510  return true;
511  default:
512  if (auto *CI = dyn_cast<CallInst>(Inst))
513  if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
514  // Remove calls to @llvm.objc.clang.arc.noop.use(...).
515  Changed = true;
516  CI->eraseFromParent();
517  }
518  return true;
519  }
520 }
521 
522 //===----------------------------------------------------------------------===//
523 // Top Level Driver
524 //===----------------------------------------------------------------------===//
525 
526 bool ObjCARCContract::init(Module &M) {
527  EP.init(&M);
528 
529  // Initialize RVInstMarker.
530  RVInstMarker = getRVInstMarker(M);
531 
532  return false;
533 }
534 
535 bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
536  if (!EnableARCOpts)
537  return false;
538 
539  Changed = CFGChanged = false;
540  AA = A;
541  DT = D;
542  PA.setAA(A);
543  BundledRetainClaimRVs BRV(true);
544  BundledInsts = &BRV;
545 
546  std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
547  Changed |= R.first;
548  CFGChanged |= R.second;
549 
551  if (F.hasPersonalityFn() &&
552  isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
553  BlockColors = colorEHFunclets(F);
554 
555  LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
556 
557  // Track whether it's ok to mark objc_storeStrong calls with the "tail"
558  // keyword. Be conservative if the function has variadic arguments.
559  // It seems that functions which "return twice" are also unsafe for the
560  // "tail" argument, because they are setjmp, which could need to
561  // return to an earlier stack state.
562  bool TailOkForStoreStrongs =
563  !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
564 
565  // For ObjC library calls which return their argument, replace uses of the
566  // argument with uses of the call return value, if it dominates the use. This
567  // reduces register pressure.
568  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
569  Instruction *Inst = &*I++;
570 
571  LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
572 
573  if (auto *CI = dyn_cast<CallInst>(Inst))
575  BundledInsts->insertRVCallWithColors(&*I, CI, BlockColors);
576  --I;
577  Changed = true;
578  }
579 
580  // First try to peephole Inst. If there is nothing further we can do in
581  // terms of undoing objc-arc-expand, process the next inst.
582  if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
583  BlockColors))
584  continue;
585 
586  // Otherwise, try to undo objc-arc-expand.
587 
588  // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
589  // and such; to do the replacement, the argument must have type i8*.
590 
591  // Function for replacing uses of Arg dominated by Inst.
592  auto ReplaceArgUses = [Inst, this](Value *Arg) {
593  // If we're compiling bugpointed code, don't get in trouble.
594  if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
595  return;
596 
597  // Look through the uses of the pointer.
598  for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
599  UI != UE; ) {
600  // Increment UI now, because we may unlink its element.
601  Use &U = *UI++;
602  unsigned OperandNo = U.getOperandNo();
603 
604  // If the call's return value dominates a use of the call's argument
605  // value, rewrite the use to use the return value. We check for
606  // reachability here because an unreachable call is considered to
607  // trivially dominate itself, which would lead us to rewriting its
608  // argument in terms of its return value, which would lead to
609  // infinite loops in GetArgRCIdentityRoot.
610  if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
611  continue;
612 
613  Changed = true;
614  Instruction *Replacement = Inst;
615  Type *UseTy = U.get()->getType();
616  if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
617  // For PHI nodes, insert the bitcast in the predecessor block.
618  unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
619  BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
620  if (Replacement->getType() != UseTy) {
621  // A catchswitch is both a pad and a terminator, meaning a basic
622  // block with a catchswitch has no insertion point. Keep going up
623  // the dominator tree until we find a non-catchswitch.
624  BasicBlock *InsertBB = IncomingBB;
625  while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) {
626  InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
627  }
628 
629  assert(DT->dominates(Inst, &InsertBB->back()) &&
630  "Invalid insertion point for bitcast");
631  Replacement =
632  new BitCastInst(Replacement, UseTy, "", &InsertBB->back());
633  }
634 
635  // While we're here, rewrite all edges for this PHI, rather
636  // than just one use at a time, to minimize the number of
637  // bitcasts we emit.
638  for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
639  if (PHI->getIncomingBlock(i) == IncomingBB) {
640  // Keep the UI iterator valid.
641  if (UI != UE &&
642  &PHI->getOperandUse(
644  ++UI;
645  PHI->setIncomingValue(i, Replacement);
646  }
647  } else {
648  if (Replacement->getType() != UseTy)
649  Replacement = new BitCastInst(Replacement, UseTy, "",
650  cast<Instruction>(U.getUser()));
651  U.set(Replacement);
652  }
653  }
654  };
655 
656  Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
657  Value *OrigArg = Arg;
658 
659  // TODO: Change this to a do-while.
660  for (;;) {
661  ReplaceArgUses(Arg);
662 
663  // If Arg is a no-op casted pointer, strip one level of casts and iterate.
664  if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
665  Arg = BI->getOperand(0);
666  else if (isa<GEPOperator>(Arg) &&
667  cast<GEPOperator>(Arg)->hasAllZeroIndices())
668  Arg = cast<GEPOperator>(Arg)->getPointerOperand();
669  else if (isa<GlobalAlias>(Arg) &&
670  !cast<GlobalAlias>(Arg)->isInterposable())
671  Arg = cast<GlobalAlias>(Arg)->getAliasee();
672  else {
673  // If Arg is a PHI node, get PHIs that are equivalent to it and replace
674  // their uses.
675  if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
676  SmallVector<Value *, 1> PHIList;
677  getEquivalentPHIs(*PN, PHIList);
678  for (Value *PHI : PHIList)
679  ReplaceArgUses(PHI);
680  }
681  break;
682  }
683  }
684 
685  // Replace bitcast users of Arg that are dominated by Inst.
686  SmallVector<BitCastInst *, 2> BitCastUsers;
687 
688  // Add all bitcast users of the function argument first.
689  for (User *U : OrigArg->users())
690  if (auto *BC = dyn_cast<BitCastInst>(U))
691  BitCastUsers.push_back(BC);
692 
693  // Replace the bitcasts with the call return. Iterate until list is empty.
694  while (!BitCastUsers.empty()) {
695  auto *BC = BitCastUsers.pop_back_val();
696  for (User *U : BC->users())
697  if (auto *B = dyn_cast<BitCastInst>(U))
698  BitCastUsers.push_back(B);
699 
700  ReplaceArgUses(BC);
701  }
702  }
703 
704  // If this function has no escaping allocas or suspicious vararg usage,
705  // objc_storeStrong calls can be marked with the "tail" keyword.
706  if (TailOkForStoreStrongs)
707  for (CallInst *CI : StoreStrongCalls)
708  CI->setTailCall();
709  StoreStrongCalls.clear();
710 
711  return Changed;
712 }
713 
714 //===----------------------------------------------------------------------===//
715 // Misc Pass Manager
716 //===----------------------------------------------------------------------===//
717 
719 INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
720  "ObjC ARC contraction", false, false)
723 INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
724  "ObjC ARC contraction", false, false)
725 
726 void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
727  AU.addRequired<AAResultsWrapperPass>();
728  AU.addRequired<DominatorTreeWrapperPass>();
729 }
730 
732  return new ObjCARCContractLegacyPass();
733 }
734 
735 bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
736  return OCARCC.init(M);
737 }
738 
740  auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
741  auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
742  return OCARCC.run(F, AA, DT);
743 }
744 
747  ObjCARCContract OCAC;
748  OCAC.init(*F.getParent());
749 
750  bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
752  bool CFGChanged = OCAC.hasCFGChanged();
753  if (Changed) {
755  if (!CFGChanged)
756  PA.preserveSet<CFGAnalyses>();
757  return PA;
758  }
759  return PreservedAnalyses::all();
760 }
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
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::objcarc::hasAttachedCallOpBundle
bool hasAttachedCallOpBundle(const CallBase *CB)
Definition: ObjCARCUtil.h:29
llvm::objcarc::ARCRuntimeEntryPointKind::RetainAutoreleaseRV
@ RetainAutoreleaseRV
llvm::objcarc::ARCRuntimeEntryPointKind::StoreStrong
@ StoreStrong
llvm::CallInst::setTailCall
void setTailCall(bool IsTc=true)
Definition: Instructions.h:1682
contract
objc arc contract
Definition: ObjCARCContract.cpp:723
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:779
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:610
llvm::BitCastInst
This class represents a no-op cast from one type to another.
Definition: Instructions.h:5200
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Statistic.h
InlineAsm.h
llvm::PHINode::getOperandNumForIncomingValue
static unsigned getOperandNumForIncomingValue(unsigned i)
Definition: Instructions.h:2739
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:325
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::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
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:635
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:201
llvm::objcarc::ARCInstKind::Autorelease
@ Autorelease
objc_autorelease
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:193
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:163
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:1335
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:287
llvm::BasicBlock::begin
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:296
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:287
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::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
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:2743
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::Use::set
void set(Value *Val)
Definition: Value.h:864
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:304
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:651
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:1757
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::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
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:311
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:745
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:532
llvm::ms_demangle::IntrinsicFunctionKind::New
@ New
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:990
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:273
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:175
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:687
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:724
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::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:186
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:1338
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:2633
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:1475
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:731
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:218
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:37