LLVM 22.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
29#include "DependencyAnalysis.h"
30#include "ObjCARC.h"
31#include "ProvenanceAnalysis.h"
32#include "llvm/ADT/Statistic.h"
36#include "llvm/IR/Dominators.h"
38#include "llvm/IR/InlineAsm.h"
40#include "llvm/IR/Operator.h"
41#include "llvm/IR/PassManager.h"
43#include "llvm/Support/Debug.h"
47
48using namespace llvm;
49using namespace llvm::objcarc;
50
51#define DEBUG_TYPE "objc-arc-contract"
52
53STATISTIC(NumPeeps, "Number of calls peephole-optimized");
54STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
55
57 "arc-contract-use-objc-claim-rv",
59 "Enable generation of calls to objc_claimAutoreleasedReturnValue"));
60
61//===----------------------------------------------------------------------===//
62// Declarations
63//===----------------------------------------------------------------------===//
64
65namespace {
66/// Late ARC optimizations
67///
68/// These change the IR in a way that makes it difficult to be analyzed by
69/// ObjCARCOpt, so it's run late.
70
71class ObjCARCContract {
72 bool Changed;
73 bool CFGChanged = false;
75 DominatorTree *DT;
78 BundledRetainClaimRVs *BundledInsts = nullptr;
79
80 /// A flag indicating whether this optimization pass should run.
81 bool Run;
82
83 /// Whether objc_claimAutoreleasedReturnValue is available.
84 bool HasClaimRV = false;
85
86 /// The inline asm string to insert between calls and RetainRV calls to make
87 /// the optimization work on targets which need it.
88 const MDString *RVInstMarker;
89
90 /// The set of inserted objc_storeStrong calls. If at the end of walking the
91 /// function we have found no alloca instructions, these calls can be marked
92 /// "tail".
93 SmallPtrSet<CallInst *, 8> StoreStrongCalls;
94
95 /// Returns true if we eliminated Inst.
96 bool tryToPeepholeInstruction(
97 Function &F, Instruction *Inst, inst_iterator &Iter,
98 bool &TailOkForStoreStrong,
99 const DenseMap<BasicBlock *, ColorVector> &BlockColors);
100
101 bool optimizeRetainCall(Function &F, Instruction *Retain);
102
103 bool contractAutorelease(Function &F, Instruction *Autorelease,
104 ARCInstKind Class);
105
106 void tryToContractReleaseIntoStoreStrong(
108 const DenseMap<BasicBlock *, ColorVector> &BlockColors);
109
110public:
111 bool init(Module &M);
112 bool run(Function &F, AAResults *AA, DominatorTree *DT);
113 bool hasCFGChanged() const { return CFGChanged; }
114};
115
116class ObjCARCContractLegacyPass : public FunctionPass {
117public:
118 void getAnalysisUsage(AnalysisUsage &AU) const override;
119 bool runOnFunction(Function &F) override;
120
121 static char ID;
122 ObjCARCContractLegacyPass() : FunctionPass(ID) {
124 }
125};
126}
127
128//===----------------------------------------------------------------------===//
129// Implementation
130//===----------------------------------------------------------------------===//
131
132/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
133/// return value. We do this late so we do not disrupt the dataflow analysis in
134/// ObjCARCOpt.
135bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
137 if (!Call)
138 return false;
139 if (Call->getParent() != Retain->getParent())
140 return false;
141
142 // Check that the call is next to the retain.
144 while (IsNoopInstruction(&*I))
145 ++I;
146 if (&*I != Retain)
147 return false;
148
149 // Turn it to an objc_retainAutoreleasedReturnValue.
150 Changed = true;
151 ++NumPeeps;
152
154 dbgs() << "Transforming objc_retain => "
155 "objc_retainAutoreleasedReturnValue since the operand is a "
156 "return value.\nOld: "
157 << *Retain << "\n");
158
159 // We do not have to worry about tail calls/does not throw since
160 // retain/retainRV have the same properties.
161 Function *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV);
162 cast<CallInst>(Retain)->setCalledFunction(Decl);
163
164 LLVM_DEBUG(dbgs() << "New: " << *Retain << "\n");
165 return true;
166}
167
168/// Merge an autorelease with a retain into a fused call.
169bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
170 ARCInstKind Class) {
172
173 // Check that there are no instructions between the retain and the autorelease
174 // (such as an autorelease_pop) which may change the count.
175 DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
180
181 if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
183 return false;
184
185 Changed = true;
186 ++NumPeeps;
187
188 LLVM_DEBUG(dbgs() << " Fusing retain/autorelease!\n"
189 " Autorelease:"
190 << *Autorelease
191 << "\n"
192 " Retain: "
193 << *Retain << "\n");
194
195 Function *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
196 ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV
197 : ARCRuntimeEntryPointKind::RetainAutorelease);
199
200 LLVM_DEBUG(dbgs() << " New RetainAutorelease: " << *Retain << "\n");
201
203 return true;
204}
205
209 AAResults *AA) {
210 StoreInst *Store = nullptr;
211 bool SawRelease = false;
212
213 // Get the location associated with Load.
215 auto *LocPtr = Loc.Ptr->stripPointerCasts();
216
217 // Walk down to find the store and the release, which may be in either order.
218 for (auto I = std::next(BasicBlock::iterator(Load)),
219 E = Load->getParent()->end();
220 I != E; ++I) {
221 // If we found the store we were looking for and saw the release,
222 // break. There is no more work to be done.
223 if (Store && SawRelease)
224 break;
225
226 // Now we know that we have not seen either the store or the release. If I
227 // is the release, mark that we saw the release and continue.
228 Instruction *Inst = &*I;
229 if (Inst == Release) {
230 SawRelease = true;
231 continue;
232 }
233
234 // Otherwise, we check if Inst is a "good" store. Grab the instruction class
235 // of Inst.
236 ARCInstKind Class = GetBasicARCInstKind(Inst);
237
238 // If we have seen the store, but not the release...
239 if (Store) {
240 // We need to make sure that it is safe to move the release from its
241 // current position to the store. This implies proving that any
242 // instruction in between Store and the Release conservatively can not use
243 // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
244 // continue...
245 if (!CanUse(Inst, Load, PA, Class)) {
246 continue;
247 }
248
249 // Otherwise, be conservative and return nullptr.
250 return nullptr;
251 }
252
253 // Ok, now we know we have not seen a store yet.
254
255 // If Inst is a retain, we don't care about it as it doesn't prevent moving
256 // the load to the store.
257 //
258 // TODO: This is one area where the optimization could be made more
259 // aggressive.
260 if (IsRetain(Class))
261 continue;
262
263 // See if Inst can write to our load location, if it can not, just ignore
264 // the instruction.
265 if (!isModSet(AA->getModRefInfo(Inst, Loc)))
266 continue;
267
268 Store = dyn_cast<StoreInst>(Inst);
269
270 // If Inst can, then check if Inst is a simple store. If Inst is not a
271 // store or a store that is not simple, then we have some we do not
272 // understand writing to this memory implying we can not move the load
273 // over the write to any subsequent store that we may find.
274 if (!Store || !Store->isSimple())
275 return nullptr;
276
277 // Then make sure that the pointer we are storing to is Ptr. If so, we
278 // found our Store!
279 if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
280 continue;
281
282 // Otherwise, we have an unknown store to some other ptr that clobbers
283 // Loc.Ptr. Bail!
284 return nullptr;
285 }
286
287 // If we did not find the store or did not see the release, fail.
288 if (!Store || !SawRelease)
289 return nullptr;
290
291 // We succeeded!
292 return Store;
293}
294
295static Instruction *
298 ProvenanceAnalysis &PA) {
299 // Walk up from the Store to find the retain.
300 BasicBlock::iterator I = Store->getIterator();
301 BasicBlock::iterator Begin = Store->getParent()->begin();
302 while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
303 Instruction *Inst = &*I;
304
305 // It is only safe to move the retain to the store if we can prove
306 // conservatively that nothing besides the release can decrement reference
307 // counts in between the retain and the store.
308 if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
309 return nullptr;
310 --I;
311 }
312 Instruction *Retain = &*I;
314 return nullptr;
315 if (GetArgRCIdentityRoot(Retain) != New)
316 return nullptr;
317 return Retain;
318}
319
320/// Attempt to merge an objc_release with a store, load, and objc_retain to form
321/// an objc_storeStrong. An objc_storeStrong:
322///
323/// objc_storeStrong(i8** %old_ptr, i8* new_value)
324///
325/// is equivalent to the following IR sequence:
326///
327/// ; Load old value.
328/// %old_value = load i8** %old_ptr (1)
329///
330/// ; Increment the new value and then release the old value. This must occur
331/// ; in order in case old_value releases new_value in its destructor causing
332/// ; us to potentially have a dangling ptr.
333/// tail call i8* @objc_retain(i8* %new_value) (2)
334/// tail call void @objc_release(i8* %old_value) (3)
335///
336/// ; Store the new_value into old_ptr
337/// store i8* %new_value, i8** %old_ptr (4)
338///
339/// The safety of this optimization is based around the following
340/// considerations:
341///
342/// 1. We are forming the store strong at the store. Thus to perform this
343/// optimization it must be safe to move the retain, load, and release to
344/// (4).
345/// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
346/// safe.
347void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
348 Instruction *Release, inst_iterator &Iter,
349 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
350 // See if we are releasing something that we just loaded.
352 if (!Load || !Load->isSimple())
353 return;
354
355 // For now, require everything to be in one basic block.
356 BasicBlock *BB = Release->getParent();
357 if (Load->getParent() != BB)
358 return;
359
360 // First scan down the BB from Load, looking for a store of the RCIdentityRoot
361 // of Load's
362 StoreInst *Store =
364 // If we fail, bail.
365 if (!Store)
366 return;
367
368 // Then find what new_value's RCIdentity Root is.
369 Value *New = GetRCIdentityRoot(Store->getValueOperand());
370
371 // Then walk up the BB and look for a retain on New without any intervening
372 // instructions which conservatively might decrement ref counts.
375
376 // If we fail, bail.
377 if (!Retain)
378 return;
379
380 Changed = true;
381 ++NumStoreStrongs;
382
384 llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n"
385 << " Old:\n"
386 << " Store: " << *Store << "\n"
387 << " Release: " << *Release << "\n"
388 << " Retain: " << *Retain << "\n"
389 << " Load: " << *Load << "\n");
390
391 Value *Args[] = {Load->getPointerOperand(), New};
392 Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
394 Decl, Args, "", Store->getIterator(), BlockColors);
395 StoreStrong->setDoesNotThrow();
396 StoreStrong->setDebugLoc(Store->getDebugLoc());
397
398 // We can't set the tail flag yet, because we haven't yet determined
399 // whether there are any escaping allocas. Remember this call, so that
400 // we can set the tail flag once we know it's safe.
401 StoreStrongCalls.insert(StoreStrong);
402
403 LLVM_DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong
404 << "\n");
405
406 if (&*Iter == Retain) ++Iter;
407 if (&*Iter == Store) ++Iter;
408 Store->eraseFromParent();
409 Release->eraseFromParent();
411 if (Load->use_empty())
412 Load->eraseFromParent();
413}
414
415bool ObjCARCContract::tryToPeepholeInstruction(
416 Function &F, Instruction *Inst, inst_iterator &Iter,
417 bool &TailOkForStoreStrongs,
418 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
419 // Only these library routines return their argument. In particular,
420 // objc_retainBlock does not necessarily return its argument.
422 switch (Class) {
423 case ARCInstKind::FusedRetainAutorelease:
424 case ARCInstKind::FusedRetainAutoreleaseRV:
425 return false;
426 case ARCInstKind::Autorelease:
427 case ARCInstKind::AutoreleaseRV:
428 return contractAutorelease(F, Inst, Class);
429 case ARCInstKind::Retain:
430 // Attempt to convert retains to retainrvs if they are next to function
431 // calls.
432 if (!optimizeRetainCall(F, Inst))
433 return false;
434 // If we succeed in our optimization, fall through.
435 [[fallthrough]];
436 case ARCInstKind::RetainRV:
437 case ARCInstKind::UnsafeClaimRV: {
438 // Return true if this is a bundled retainRV/claimRV call, which is always
439 // redundant with the attachedcall in the bundle, and is going to be erased
440 // at the end of this pass. This avoids undoing objc-arc-expand and
441 // replacing uses of the retainRV/claimRV call's argument with its result.
442 if (BundledInsts->contains(Inst))
443 return true;
444
445 // If this isn't a bundled call, and the target doesn't need a special
446 // inline-asm marker, we're done: return now, and undo objc-arc-expand.
447 if (!RVInstMarker)
448 return false;
449
450 // The target needs a special inline-asm marker. Insert it.
451
452 BasicBlock::iterator BBI = Inst->getIterator();
453 BasicBlock *InstParent = Inst->getParent();
454
455 // Step up to see if the call immediately precedes the RV call.
456 // If it's an invoke, we have to cross a block boundary. And we have
457 // to carefully dodge no-op instructions.
458 do {
459 if (BBI == InstParent->begin()) {
460 BasicBlock *Pred = InstParent->getSinglePredecessor();
461 if (!Pred)
462 goto decline_rv_optimization;
463 BBI = Pred->getTerminator()->getIterator();
464 break;
465 }
466 --BBI;
467 } while (IsNoopInstruction(&*BBI));
468
469 if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
470 LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
471 "optimization.\n");
472 Changed = true;
473 InlineAsm *IA =
474 InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()),
475 /*isVarArg=*/false),
476 RVInstMarker->getString(),
477 /*Constraints=*/"", /*hasSideEffects=*/true);
478
480 BlockColors);
481 }
482 decline_rv_optimization:
483 return false;
484 }
485 case ARCInstKind::InitWeak: {
486 // objc_initWeak(p, null) => *p = null
487 CallInst *CI = cast<CallInst>(Inst);
488 if (IsNullOrUndef(CI->getArgOperand(1))) {
490 Changed = true;
491 new StoreInst(Null, CI->getArgOperand(0), CI->getIterator());
492
493 LLVM_DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
494 << " New = " << *Null << "\n");
495
497 CI->eraseFromParent();
498 }
499 return true;
500 }
501 case ARCInstKind::Release:
502 // Try to form an objc store strong from our release. If we fail, there is
503 // nothing further to do below, so continue.
504 tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
505 return true;
506 case ARCInstKind::User:
507 // Be conservative if the function has any alloca instructions.
508 // Technically we only care about escaping alloca instructions,
509 // but this is sufficient to handle some interesting cases.
510 if (isa<AllocaInst>(Inst))
511 TailOkForStoreStrongs = false;
512 return true;
513 case ARCInstKind::IntrinsicUser:
514 // Remove calls to @llvm.objc.clang.arc.use(...).
515 Changed = true;
516 Inst->eraseFromParent();
517 return true;
518 default:
519 if (auto *CI = dyn_cast<CallInst>(Inst))
520 if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
521 // Remove calls to @llvm.objc.clang.arc.noop.use(...).
522 Changed = true;
523 CI->eraseFromParent();
524 }
525 return true;
526 }
527}
528
529/// Should we use objc_claimAutoreleasedReturnValue?
531 // Let the flag override our OS-based default.
534
535 Triple TT(M.getTargetTriple());
536
537 // On x86_64, claimARV doesn't make sense, as the marker isn't actually a nop
538 // there (it's needed by the calling convention).
539 if (!TT.isAArch64())
540 return false;
541
542 unsigned Major = TT.getOSMajorVersion();
543 switch (TT.getOS()) {
544 default:
545 return false;
546 case Triple::IOS:
547 case Triple::TvOS:
548 return Major >= 16;
549 case Triple::WatchOS:
550 return Major >= 9;
551 case Triple::BridgeOS:
552 return Major >= 7;
553 case Triple::MacOSX:
554 return Major >= 13;
555 case Triple::Darwin:
556 return Major >= 21;
557 }
558
559 return false;
560}
561
562//===----------------------------------------------------------------------===//
563// Top Level Driver
564//===----------------------------------------------------------------------===//
565
566bool ObjCARCContract::init(Module &M) {
567 Run = ModuleHasARC(M);
568 if (!Run)
569 return false;
570
571 EP.init(&M);
572
573 HasClaimRV = useClaimRuntimeCall(M);
574
575 // Initialize RVInstMarker.
576 RVInstMarker = getRVInstMarker(M);
577
578 return false;
579}
580
581bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
582 if (!Run)
583 return false;
584
585 if (!EnableARCOpts)
586 return false;
587
588 Changed = CFGChanged = false;
589 AA = A;
590 DT = D;
591 PA.setAA(A);
592 BundledRetainClaimRVs BRV(EP, /*ContractPass=*/true, HasClaimRV);
593 BundledInsts = &BRV;
594
595 std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
596 Changed |= R.first;
597 CFGChanged |= R.second;
598
599 DenseMap<BasicBlock *, ColorVector> BlockColors;
600 if (F.hasPersonalityFn() &&
601 isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
602 BlockColors = colorEHFunclets(F);
603
604 LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
605
606 // Track whether it's ok to mark objc_storeStrong calls with the "tail"
607 // keyword. Be conservative if the function has variadic arguments.
608 // It seems that functions which "return twice" are also unsafe for the
609 // "tail" argument, because they are setjmp, which could need to
610 // return to an earlier stack state.
611 bool TailOkForStoreStrongs =
612 !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
613
614 // For ObjC library calls which return their argument, replace uses of the
615 // argument with uses of the call return value, if it dominates the use. This
616 // reduces register pressure.
617 for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
618 Instruction *Inst = &*I++;
619
620 LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
621
622 if (auto *CI = dyn_cast<CallInst>(Inst))
624 BundledInsts->insertRVCallWithColors(I->getIterator(), CI, BlockColors);
625 --I;
626 Changed = true;
627 }
628
629 // First try to peephole Inst. If there is nothing further we can do in
630 // terms of undoing objc-arc-expand, process the next inst.
631 if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
632 BlockColors))
633 continue;
634
635 // Otherwise, try to undo objc-arc-expand.
636
637 // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
638 // and such; to do the replacement, the argument must have type i8*.
639
640 // Function for replacing uses of Arg dominated by Inst.
641 auto ReplaceArgUses = [Inst, this](Value *Arg) {
642 // If we're compiling bugpointed code, don't get in trouble.
643 if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
644 return;
645
646 // Look through the uses of the pointer.
647 for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
648 UI != UE; ) {
649 // Increment UI now, because we may unlink its element.
650 Use &U = *UI++;
651 unsigned OperandNo = U.getOperandNo();
652
653 // If the call's return value dominates a use of the call's argument
654 // value, rewrite the use to use the return value. We check for
655 // reachability here because an unreachable call is considered to
656 // trivially dominate itself, which would lead us to rewriting its
657 // argument in terms of its return value, which would lead to
658 // infinite loops in GetArgRCIdentityRoot.
659 if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
660 continue;
661
662 Changed = true;
663 Instruction *Replacement = Inst;
664 Type *UseTy = U.get()->getType();
665 if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
666 // For PHI nodes, insert the bitcast in the predecessor block.
667 unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
668 BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
669 if (Replacement->getType() != UseTy) {
670 // A catchswitch is both a pad and a terminator, meaning a basic
671 // block with a catchswitch has no insertion point. Keep going up
672 // the dominator tree until we find a non-catchswitch.
673 BasicBlock *InsertBB = IncomingBB;
674 while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHIIt())) {
675 InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
676 }
677
678 assert(DT->dominates(Inst, &InsertBB->back()) &&
679 "Invalid insertion point for bitcast");
680 Replacement = new BitCastInst(Replacement, UseTy, "",
681 InsertBB->back().getIterator());
682 }
683
684 // While we're here, rewrite all edges for this PHI, rather
685 // than just one use at a time, to minimize the number of
686 // bitcasts we emit.
687 for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
688 if (PHI->getIncomingBlock(i) == IncomingBB) {
689 // Keep the UI iterator valid.
690 if (UI != UE &&
691 &PHI->getOperandUse(
693 ++UI;
694 PHI->setIncomingValue(i, Replacement);
695 }
696 } else {
697 if (Replacement->getType() != UseTy)
698 Replacement =
699 new BitCastInst(Replacement, UseTy, "",
700 cast<Instruction>(U.getUser())->getIterator());
701 U.set(Replacement);
702 }
703 }
704 };
705
706 Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
707
708 // TODO: Change this to a do-while.
709 for (;;) {
710 ReplaceArgUses(Arg);
711
712 // If Arg is a no-op casted pointer, strip one level of casts and iterate.
713 if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
714 Arg = BI->getOperand(0);
715 else if (isa<GEPOperator>(Arg) &&
716 cast<GEPOperator>(Arg)->hasAllZeroIndices())
717 Arg = cast<GEPOperator>(Arg)->getPointerOperand();
718 else if (isa<GlobalAlias>(Arg) &&
719 !cast<GlobalAlias>(Arg)->isInterposable())
720 Arg = cast<GlobalAlias>(Arg)->getAliasee();
721 else {
722 // If Arg is a PHI node, get PHIs that are equivalent to it and replace
723 // their uses.
724 if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
726 getEquivalentPHIs(*PN, PHIList);
727 for (Value *PHI : PHIList)
728 ReplaceArgUses(PHI);
729 }
730 break;
731 }
732 }
733 }
734
735 // If this function has no escaping allocas or suspicious vararg usage,
736 // objc_storeStrong calls can be marked with the "tail" keyword.
737 if (TailOkForStoreStrongs)
738 for (CallInst *CI : StoreStrongCalls)
739 CI->setTailCall();
740 StoreStrongCalls.clear();
741
742 return Changed;
743}
744
745//===----------------------------------------------------------------------===//
746// Misc Pass Manager
747//===----------------------------------------------------------------------===//
748
749char ObjCARCContractLegacyPass::ID = 0;
750INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
751 "ObjC ARC contraction", false, false)
754INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
755 "ObjC ARC contraction", false, false)
756
757void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
758 AU.addRequired<AAResultsWrapperPass>();
759 AU.addRequired<DominatorTreeWrapperPass>();
760 AU.addPreserved<AAResultsWrapperPass>();
761 AU.addPreserved<BasicAAWrapperPass>();
762 AU.addPreserved<DominatorTreeWrapperPass>();
763}
764
766 return new ObjCARCContractLegacyPass();
767}
768
769bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
770 ObjCARCContract OCARCC;
771 OCARCC.init(*F.getParent());
772 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
773 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
774 return OCARCC.run(F, AA, DT);
775}
776
779 ObjCARCContract OCAC;
780 OCAC.init(*F.getParent());
781
782 bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
784 bool CFGChanged = OCAC.hasCFGChanged();
785 if (Changed) {
787 if (!CFGChanged)
789 return PA;
790 }
791 return PreservedAnalyses::all();
792}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
This file contains a class ARCRuntimeEntryPoints for use in creating/managing references to entry poi...
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file declares special dependency analysis routines used in Objective C ARC Optimizations.
static bool runOnFunction(Function &F, bool PostInlining)
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
Machine Check Debug Module
static StoreInst * findSafeStoreForStoreStrongContraction(LoadInst *Load, Instruction *Release, ProvenanceAnalysis &PA, AAResults *AA)
static bool useClaimRuntimeCall(Module &M)
Should we use objc_claimAutoreleasedReturnValue?
static Instruction * findRetainForStoreStrongContraction(Value *New, StoreInst *Store, Instruction *Release, ProvenanceAnalysis &PA)
static cl::opt< cl::boolOrDefault > UseObjCClaimRV("arc-contract-use-objc-claim-rv", cl::desc("Enable generation of calls to objc_claimAutoreleasedReturnValue"))
This file defines ARC utility functions which are used by various parts of the compiler.
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file declares a special form of Alias Analysis called Provenance / Analysis''.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:167
#define LLVM_DEBUG(...)
Definition Debug.h:119
void setAA(AAResults *aa)
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
Legacy wrapper pass to provide the BasicAAResult object.
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:459
const Instruction & back() const
Definition BasicBlock.h:484
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
Definition BasicBlock.h:171
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
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.h:233
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Value * getArgOperand(unsigned i) const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
void setTailCall(bool IsTc=true)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
DomTreeNodeBase * getIDom() const
NodeT * getBlock() const
Analysis pass which computes a DominatorTree.
Definition Dominators.h:284
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:322
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
static LLVM_ABI 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:43
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
An instruction for reading from memory.
A single uniqued string.
Definition Metadata.h:720
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:617
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static unsigned getOperandNumForIncomingValue(unsigned i)
static unsigned getIncomingValueNumForOperand(unsigned i)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
An instruction for storing to memory.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:546
use_iterator use_begin()
Definition Value.h:364
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1101
use_iterator use_end()
Definition Value.h:372
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:134
Declarations for ObjC runtime functions and constants.
Function * get(ARCRuntimeEntryPointKind kind)
bool contains(const Instruction *I) const
See if an instruction is a bundled retainRV/claimRV call.
Definition ObjCARC.h:128
std::pair< bool, bool > insertAfterInvokes(Function &F, DominatorTree *DT)
Insert a retainRV/claimRV call to the normal destination blocks of invokes with operand bundle "clang...
Definition ObjCARC.cpp:44
CallInst * insertRVCallWithColors(BasicBlock::iterator InsertPt, CallBase *AnnotatedCall, const DenseMap< BasicBlock *, ColorVector > &BlockColors)
Insert a retainRV/claimRV call with colors.
Definition ObjCARC.cpp:80
CallInst * Retain
CallInst * Call
Changed
CallInst * Autorelease
Look for an `‘autorelease’' instruction dependent on Arg such that there are / no instructions depend...
This file defines common definitions/declarations used by the ObjC ARC Optimizer.
Abstract Attribute helper functions.
Definition Attributor.h:165
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
bool ModuleHasARC(const Module &M)
Test if the given module looks interesting to run ARC optimization on.
bool IsRetain(ARCInstKind Class)
Test if the given class is objc_retain or equivalent.
DependenceKind
Defines different dependence kinds among various ARC constructs.
@ RetainAutoreleaseDep
Blocks objc_retainAutorelease.
@ RetainAutoreleaseRVDep
Blocks objc_retainAutoreleaseReturnValue.
bool IsNullOrUndef(const Value *V)
ARCInstKind
Equivalence classes of instructions in the ARC Model.
@ StoreStrong
objc_storeStrong (derived)
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
CallInst * createCallInstWithColors(FunctionCallee Func, ArrayRef< Value * > Args, const Twine &NameStr, BasicBlock::iterator InsertBefore, const DenseMap< BasicBlock *, ColorVector > &BlockColors)
Create a call instruction with the correct funclet token.
Definition ObjCARC.cpp:24
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList)
Return the list of PHI nodes that are equivalent to PN.
Definition ObjCARC.h:75
bool IsNoopInstruction(const Instruction *I)
llvm::Instruction * findSingleDependency(DependenceKind Flavor, const Value *Arg, BasicBlock *StartBB, Instruction *StartInst, ProvenanceAnalysis &PA)
Find dependent instructions.
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
Value * GetArgRCIdentityRoot(Value *Inst)
Assuming the given instruction is one of the special calls such as objc_retain or objc_release,...
bool CanDecrementRefCount(ARCInstKind Kind)
Returns false if conservatively we can prove that any instruction mapped to this kind can not decreme...
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...
static MDString * getRVInstMarker(Module &M)
Definition ObjCARC.h:93
bool hasAttachedCallOpBundle(const CallBase *CB)
Definition ObjCARCUtil.h:29
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...
static void EraseInstruction(Instruction *CI)
Erase the given instruction.
Definition ObjCARC.h:40
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
InstIterator< SymbolTableList< BasicBlock >, Function::iterator, BasicBlock::iterator, Instruction > inst_iterator
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
LLVM_ABI void initializeObjCARCContractLegacyPassPass(PassRegistry &)
inst_iterator inst_begin(Function *F)
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:759
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
inst_iterator inst_end(Function *F)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Pass * createObjCARCContractPass()
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)