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"
33 #include "llvm/Analysis/AliasAnalysis.h"
34 #include "llvm/Analysis/EHPersonalities.h"
35 #include "llvm/IR/Dominators.h"
36 #include "llvm/IR/InlineAsm.h"
37 #include "llvm/IR/InstIterator.h"
38 #include "llvm/IR/Operator.h"
39 #include "llvm/IR/PassManager.h"
40 #include "llvm/InitializePasses.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include "llvm/Transforms/ObjCARC.h"
45
46 using namespace llvm;
47 using namespace llvm::objcarc;
48
49 #define DEBUG_TYPE "objc-arc-contract"
50
51 STATISTIC(NumPeeps, "Number of calls peephole-optimized");
52 STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
53
54 //===----------------------------------------------------------------------===//
55 // Declarations
56 //===----------------------------------------------------------------------===//
57
58 namespace {
59 /// Late ARC optimizations
60 ///
61 /// These change the IR in a way that makes it difficult to be analyzed by
62 /// ObjCARCOpt, so it's run late.
63
64 class ObjCARCContract {
65 bool Changed;
66 AAResults *AA;
67 DominatorTree *DT;
68 ProvenanceAnalysis PA;
69 ARCRuntimeEntryPoints EP;
70
71 /// A flag indicating whether this optimization pass should run.
72 bool Run;
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 };
102
103 class ObjCARCContractLegacyPass : public FunctionPass {
104 ObjCARCContract OCARCC;
105
106 public:
107 void getAnalysisUsage(AnalysisUsage &AU) const override;
108 bool doInitialization(Module &M) override;
109 bool runOnFunction(Function &F) override;
110
111 static char ID;
ObjCARCContractLegacyPass()112 ObjCARCContractLegacyPass() : FunctionPass(ID) {
113 initializeObjCARCContractLegacyPassPass(*PassRegistry::getPassRegistry());
114 }
115 };
116 }
117
118 //===----------------------------------------------------------------------===//
119 // Implementation
120 //===----------------------------------------------------------------------===//
121
122 /// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
123 /// return value. We do this late so we do not disrupt the dataflow analysis in
124 /// ObjCARCOpt.
optimizeRetainCall(Function & F,Instruction * Retain)125 bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
126 const auto *Call = dyn_cast<CallBase>(GetArgRCIdentityRoot(Retain));
127 if (!Call)
128 return false;
129 if (Call->getParent() != Retain->getParent())
130 return false;
131
132 // Check that the call is next to the retain.
133 BasicBlock::const_iterator I = ++Call->getIterator();
134 while (IsNoopInstruction(&*I))
135 ++I;
136 if (&*I != Retain)
137 return false;
138
139 // Turn it to an objc_retainAutoreleasedReturnValue.
140 Changed = true;
141 ++NumPeeps;
142
143 LLVM_DEBUG(
144 dbgs() << "Transforming objc_retain => "
145 "objc_retainAutoreleasedReturnValue since the operand is a "
146 "return value.\nOld: "
147 << *Retain << "\n");
148
149 // We do not have to worry about tail calls/does not throw since
150 // retain/retainRV have the same properties.
151 Function *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV);
152 cast<CallInst>(Retain)->setCalledFunction(Decl);
153
154 LLVM_DEBUG(dbgs() << "New: " << *Retain << "\n");
155 return true;
156 }
157
158 /// Merge an autorelease with a retain into a fused call.
contractAutorelease(Function & F,Instruction * Autorelease,ARCInstKind Class)159 bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
160 ARCInstKind Class) {
161 const Value *Arg = GetArgRCIdentityRoot(Autorelease);
162
163 // Check that there are no instructions between the retain and the autorelease
164 // (such as an autorelease_pop) which may change the count.
165 DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
166 ? RetainAutoreleaseRVDep
167 : RetainAutoreleaseDep;
168 auto *Retain = dyn_cast_or_null<CallInst>(
169 findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));
170
171 if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
172 GetArgRCIdentityRoot(Retain) != Arg)
173 return false;
174
175 Changed = true;
176 ++NumPeeps;
177
178 LLVM_DEBUG(dbgs() << " Fusing retain/autorelease!\n"
179 " Autorelease:"
180 << *Autorelease
181 << "\n"
182 " Retain: "
183 << *Retain << "\n");
184
185 Function *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
186 ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV
187 : ARCRuntimeEntryPointKind::RetainAutorelease);
188 Retain->setCalledFunction(Decl);
189
190 LLVM_DEBUG(dbgs() << " New RetainAutorelease: " << *Retain << "\n");
191
192 EraseInstruction(Autorelease);
193 return true;
194 }
195
findSafeStoreForStoreStrongContraction(LoadInst * Load,Instruction * Release,ProvenanceAnalysis & PA,AAResults * AA)196 static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
197 Instruction *Release,
198 ProvenanceAnalysis &PA,
199 AAResults *AA) {
200 StoreInst *Store = nullptr;
201 bool SawRelease = false;
202
203 // Get the location associated with Load.
204 MemoryLocation Loc = MemoryLocation::get(Load);
205 auto *LocPtr = Loc.Ptr->stripPointerCasts();
206
207 // Walk down to find the store and the release, which may be in either order.
208 for (auto I = std::next(BasicBlock::iterator(Load)),
209 E = Load->getParent()->end();
210 I != E; ++I) {
211 // If we found the store we were looking for and saw the release,
212 // break. There is no more work to be done.
213 if (Store && SawRelease)
214 break;
215
216 // Now we know that we have not seen either the store or the release. If I
217 // is the release, mark that we saw the release and continue.
218 Instruction *Inst = &*I;
219 if (Inst == Release) {
220 SawRelease = true;
221 continue;
222 }
223
224 // Otherwise, we check if Inst is a "good" store. Grab the instruction class
225 // of Inst.
226 ARCInstKind Class = GetBasicARCInstKind(Inst);
227
228 // If Inst is an unrelated retain, we don't care about it.
229 //
230 // TODO: This is one area where the optimization could be made more
231 // aggressive.
232 if (IsRetain(Class))
233 continue;
234
235 // If we have seen the store, but not the release...
236 if (Store) {
237 // We need to make sure that it is safe to move the release from its
238 // current position to the store. This implies proving that any
239 // instruction in between Store and the Release conservatively can not use
240 // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
241 // continue...
242 if (!CanUse(Inst, Load, PA, Class)) {
243 continue;
244 }
245
246 // Otherwise, be conservative and return nullptr.
247 return nullptr;
248 }
249
250 // Ok, now we know we have not seen a store yet. See if Inst can write to
251 // our load location, if it can not, just ignore the instruction.
252 if (!isModSet(AA->getModRefInfo(Inst, Loc)))
253 continue;
254
255 Store = dyn_cast<StoreInst>(Inst);
256
257 // If Inst can, then check if Inst is a simple store. If Inst is not a
258 // store or a store that is not simple, then we have some we do not
259 // understand writing to this memory implying we can not move the load
260 // over the write to any subsequent store that we may find.
261 if (!Store || !Store->isSimple())
262 return nullptr;
263
264 // Then make sure that the pointer we are storing to is Ptr. If so, we
265 // found our Store!
266 if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
267 continue;
268
269 // Otherwise, we have an unknown store to some other ptr that clobbers
270 // Loc.Ptr. Bail!
271 return nullptr;
272 }
273
274 // If we did not find the store or did not see the release, fail.
275 if (!Store || !SawRelease)
276 return nullptr;
277
278 // We succeeded!
279 return Store;
280 }
281
282 static Instruction *
findRetainForStoreStrongContraction(Value * New,StoreInst * Store,Instruction * Release,ProvenanceAnalysis & PA)283 findRetainForStoreStrongContraction(Value *New, StoreInst *Store,
284 Instruction *Release,
285 ProvenanceAnalysis &PA) {
286 // Walk up from the Store to find the retain.
287 BasicBlock::iterator I = Store->getIterator();
288 BasicBlock::iterator Begin = Store->getParent()->begin();
289 while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
290 Instruction *Inst = &*I;
291
292 // It is only safe to move the retain to the store if we can prove
293 // conservatively that nothing besides the release can decrement reference
294 // counts in between the retain and the store.
295 if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
296 return nullptr;
297 --I;
298 }
299 Instruction *Retain = &*I;
300 if (GetBasicARCInstKind(Retain) != ARCInstKind::Retain)
301 return nullptr;
302 if (GetArgRCIdentityRoot(Retain) != New)
303 return nullptr;
304 return Retain;
305 }
306
307 /// Create a call instruction with the correct funclet token. Should be used
308 /// instead of calling CallInst::Create directly.
309 static CallInst *
createCallInst(FunctionType * FTy,Value * Func,ArrayRef<Value * > Args,const Twine & NameStr,Instruction * InsertBefore,const DenseMap<BasicBlock *,ColorVector> & BlockColors)310 createCallInst(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
311 const Twine &NameStr, Instruction *InsertBefore,
312 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
313 SmallVector<OperandBundleDef, 1> OpBundles;
314 if (!BlockColors.empty()) {
315 const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
316 assert(CV.size() == 1 && "non-unique color for block!");
317 Instruction *EHPad = CV.front()->getFirstNonPHI();
318 if (EHPad->isEHPad())
319 OpBundles.emplace_back("funclet", EHPad);
320 }
321
322 return CallInst::Create(FTy, Func, Args, OpBundles, NameStr, InsertBefore);
323 }
324
325 static CallInst *
createCallInst(FunctionCallee Func,ArrayRef<Value * > Args,const Twine & NameStr,Instruction * InsertBefore,const DenseMap<BasicBlock *,ColorVector> & BlockColors)326 createCallInst(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
327 Instruction *InsertBefore,
328 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
329 return createCallInst(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
330 InsertBefore, BlockColors);
331 }
332
333 /// Attempt to merge an objc_release with a store, load, and objc_retain to form
334 /// an objc_storeStrong. An objc_storeStrong:
335 ///
336 /// objc_storeStrong(i8** %old_ptr, i8* new_value)
337 ///
338 /// is equivalent to the following IR sequence:
339 ///
340 /// ; Load old value.
341 /// %old_value = load i8** %old_ptr (1)
342 ///
343 /// ; Increment the new value and then release the old value. This must occur
344 /// ; in order in case old_value releases new_value in its destructor causing
345 /// ; us to potentially have a dangling ptr.
346 /// tail call i8* @objc_retain(i8* %new_value) (2)
347 /// tail call void @objc_release(i8* %old_value) (3)
348 ///
349 /// ; Store the new_value into old_ptr
350 /// store i8* %new_value, i8** %old_ptr (4)
351 ///
352 /// The safety of this optimization is based around the following
353 /// considerations:
354 ///
355 /// 1. We are forming the store strong at the store. Thus to perform this
356 /// optimization it must be safe to move the retain, load, and release to
357 /// (4).
358 /// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
359 /// safe.
tryToContractReleaseIntoStoreStrong(Instruction * Release,inst_iterator & Iter,const DenseMap<BasicBlock *,ColorVector> & BlockColors)360 void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
361 Instruction *Release, inst_iterator &Iter,
362 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
363 // See if we are releasing something that we just loaded.
364 auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
365 if (!Load || !Load->isSimple())
366 return;
367
368 // For now, require everything to be in one basic block.
369 BasicBlock *BB = Release->getParent();
370 if (Load->getParent() != BB)
371 return;
372
373 // First scan down the BB from Load, looking for a store of the RCIdentityRoot
374 // of Load's
375 StoreInst *Store =
376 findSafeStoreForStoreStrongContraction(Load, Release, PA, AA);
377 // If we fail, bail.
378 if (!Store)
379 return;
380
381 // Then find what new_value's RCIdentity Root is.
382 Value *New = GetRCIdentityRoot(Store->getValueOperand());
383
384 // Then walk up the BB and look for a retain on New without any intervening
385 // instructions which conservatively might decrement ref counts.
386 Instruction *Retain =
387 findRetainForStoreStrongContraction(New, Store, Release, PA);
388
389 // If we fail, bail.
390 if (!Retain)
391 return;
392
393 Changed = true;
394 ++NumStoreStrongs;
395
396 LLVM_DEBUG(
397 llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n"
398 << " Old:\n"
399 << " Store: " << *Store << "\n"
400 << " Release: " << *Release << "\n"
401 << " Retain: " << *Retain << "\n"
402 << " Load: " << *Load << "\n");
403
404 LLVMContext &C = Release->getContext();
405 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
406 Type *I8XX = PointerType::getUnqual(I8X);
407
408 Value *Args[] = { Load->getPointerOperand(), New };
409 if (Args[0]->getType() != I8XX)
410 Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
411 if (Args[1]->getType() != I8X)
412 Args[1] = new BitCastInst(Args[1], I8X, "", Store);
413 Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
414 CallInst *StoreStrong = createCallInst(Decl, Args, "", Store, BlockColors);
415 StoreStrong->setDoesNotThrow();
416 StoreStrong->setDebugLoc(Store->getDebugLoc());
417
418 // We can't set the tail flag yet, because we haven't yet determined
419 // whether there are any escaping allocas. Remember this call, so that
420 // we can set the tail flag once we know it's safe.
421 StoreStrongCalls.insert(StoreStrong);
422
423 LLVM_DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong
424 << "\n");
425
426 if (&*Iter == Retain) ++Iter;
427 if (&*Iter == Store) ++Iter;
428 Store->eraseFromParent();
429 Release->eraseFromParent();
430 EraseInstruction(Retain);
431 if (Load->use_empty())
432 Load->eraseFromParent();
433 }
434
tryToPeepholeInstruction(Function & F,Instruction * Inst,inst_iterator & Iter,bool & TailOkForStoreStrongs,const DenseMap<BasicBlock *,ColorVector> & BlockColors)435 bool ObjCARCContract::tryToPeepholeInstruction(
436 Function &F, Instruction *Inst, inst_iterator &Iter,
437 bool &TailOkForStoreStrongs,
438 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
439 // Only these library routines return their argument. In particular,
440 // objc_retainBlock does not necessarily return its argument.
441 ARCInstKind Class = GetBasicARCInstKind(Inst);
442 switch (Class) {
443 case ARCInstKind::FusedRetainAutorelease:
444 case ARCInstKind::FusedRetainAutoreleaseRV:
445 return false;
446 case ARCInstKind::Autorelease:
447 case ARCInstKind::AutoreleaseRV:
448 return contractAutorelease(F, Inst, Class);
449 case ARCInstKind::Retain:
450 // Attempt to convert retains to retainrvs if they are next to function
451 // calls.
452 if (!optimizeRetainCall(F, Inst))
453 return false;
454 // If we succeed in our optimization, fall through.
455 LLVM_FALLTHROUGH;
456 case ARCInstKind::RetainRV:
457 case ARCInstKind::ClaimRV: {
458 // If we're compiling for a target which needs a special inline-asm
459 // marker to do the return value optimization, insert it now.
460 if (!RVInstMarker)
461 return false;
462 BasicBlock::iterator BBI = Inst->getIterator();
463 BasicBlock *InstParent = Inst->getParent();
464
465 // Step up to see if the call immediately precedes the RV call.
466 // If it's an invoke, we have to cross a block boundary. And we have
467 // to carefully dodge no-op instructions.
468 do {
469 if (BBI == InstParent->begin()) {
470 BasicBlock *Pred = InstParent->getSinglePredecessor();
471 if (!Pred)
472 goto decline_rv_optimization;
473 BBI = Pred->getTerminator()->getIterator();
474 break;
475 }
476 --BBI;
477 } while (IsNoopInstruction(&*BBI));
478
479 if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
480 LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
481 "optimization.\n");
482 Changed = true;
483 InlineAsm *IA =
484 InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()),
485 /*isVarArg=*/false),
486 RVInstMarker->getString(),
487 /*Constraints=*/"", /*hasSideEffects=*/true);
488
489 createCallInst(IA, None, "", Inst, BlockColors);
490 }
491 decline_rv_optimization:
492 return false;
493 }
494 case ARCInstKind::InitWeak: {
495 // objc_initWeak(p, null) => *p = null
496 CallInst *CI = cast<CallInst>(Inst);
497 if (IsNullOrUndef(CI->getArgOperand(1))) {
498 Value *Null = ConstantPointerNull::get(cast<PointerType>(CI->getType()));
499 Changed = true;
500 new StoreInst(Null, CI->getArgOperand(0), CI);
501
502 LLVM_DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
503 << " New = " << *Null << "\n");
504
505 CI->replaceAllUsesWith(Null);
506 CI->eraseFromParent();
507 }
508 return true;
509 }
510 case ARCInstKind::Release:
511 // Try to form an objc store strong from our release. If we fail, there is
512 // nothing further to do below, so continue.
513 tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
514 return true;
515 case ARCInstKind::User:
516 // Be conservative if the function has any alloca instructions.
517 // Technically we only care about escaping alloca instructions,
518 // but this is sufficient to handle some interesting cases.
519 if (isa<AllocaInst>(Inst))
520 TailOkForStoreStrongs = false;
521 return true;
522 case ARCInstKind::IntrinsicUser:
523 // Remove calls to @llvm.objc.clang.arc.use(...).
524 Changed = true;
525 Inst->eraseFromParent();
526 return true;
527 default:
528 return true;
529 }
530 }
531
532 //===----------------------------------------------------------------------===//
533 // Top Level Driver
534 //===----------------------------------------------------------------------===//
535
init(Module & M)536 bool ObjCARCContract::init(Module &M) {
537 // If nothing in the Module uses ARC, don't do anything.
538 Run = ModuleHasARC(M);
539 if (!Run)
540 return false;
541
542 EP.init(&M);
543
544 // Initialize RVInstMarker.
545 const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
546 RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
547
548 return false;
549 }
550
run(Function & F,AAResults * A,DominatorTree * D)551 bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
552 if (!EnableARCOpts)
553 return false;
554
555 // If nothing in the Module uses ARC, don't do anything.
556 if (!Run)
557 return false;
558
559 Changed = false;
560 AA = A;
561 DT = D;
562 PA.setAA(A);
563
564 DenseMap<BasicBlock *, ColorVector> BlockColors;
565 if (F.hasPersonalityFn() &&
566 isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
567 BlockColors = colorEHFunclets(F);
568
569 LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
570
571 // Track whether it's ok to mark objc_storeStrong calls with the "tail"
572 // keyword. Be conservative if the function has variadic arguments.
573 // It seems that functions which "return twice" are also unsafe for the
574 // "tail" argument, because they are setjmp, which could need to
575 // return to an earlier stack state.
576 bool TailOkForStoreStrongs =
577 !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
578
579 // For ObjC library calls which return their argument, replace uses of the
580 // argument with uses of the call return value, if it dominates the use. This
581 // reduces register pressure.
582 for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
583 Instruction *Inst = &*I++;
584
585 LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
586
587 // First try to peephole Inst. If there is nothing further we can do in
588 // terms of undoing objc-arc-expand, process the next inst.
589 if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
590 BlockColors))
591 continue;
592
593 // Otherwise, try to undo objc-arc-expand.
594
595 // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
596 // and such; to do the replacement, the argument must have type i8*.
597
598 // Function for replacing uses of Arg dominated by Inst.
599 auto ReplaceArgUses = [Inst, this](Value *Arg) {
600 // If we're compiling bugpointed code, don't get in trouble.
601 if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
602 return;
603
604 // Look through the uses of the pointer.
605 for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
606 UI != UE; ) {
607 // Increment UI now, because we may unlink its element.
608 Use &U = *UI++;
609 unsigned OperandNo = U.getOperandNo();
610
611 // If the call's return value dominates a use of the call's argument
612 // value, rewrite the use to use the return value. We check for
613 // reachability here because an unreachable call is considered to
614 // trivially dominate itself, which would lead us to rewriting its
615 // argument in terms of its return value, which would lead to
616 // infinite loops in GetArgRCIdentityRoot.
617 if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
618 continue;
619
620 Changed = true;
621 Instruction *Replacement = Inst;
622 Type *UseTy = U.get()->getType();
623 if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
624 // For PHI nodes, insert the bitcast in the predecessor block.
625 unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
626 BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
627 if (Replacement->getType() != UseTy) {
628 // A catchswitch is both a pad and a terminator, meaning a basic
629 // block with a catchswitch has no insertion point. Keep going up
630 // the dominator tree until we find a non-catchswitch.
631 BasicBlock *InsertBB = IncomingBB;
632 while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) {
633 InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
634 }
635
636 assert(DT->dominates(Inst, &InsertBB->back()) &&
637 "Invalid insertion point for bitcast");
638 Replacement =
639 new BitCastInst(Replacement, UseTy, "", &InsertBB->back());
640 }
641
642 // While we're here, rewrite all edges for this PHI, rather
643 // than just one use at a time, to minimize the number of
644 // bitcasts we emit.
645 for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
646 if (PHI->getIncomingBlock(i) == IncomingBB) {
647 // Keep the UI iterator valid.
648 if (UI != UE &&
649 &PHI->getOperandUse(
650 PHINode::getOperandNumForIncomingValue(i)) == &*UI)
651 ++UI;
652 PHI->setIncomingValue(i, Replacement);
653 }
654 } else {
655 if (Replacement->getType() != UseTy)
656 Replacement = new BitCastInst(Replacement, UseTy, "",
657 cast<Instruction>(U.getUser()));
658 U.set(Replacement);
659 }
660 }
661 };
662
663 Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
664 Value *OrigArg = Arg;
665
666 // TODO: Change this to a do-while.
667 for (;;) {
668 ReplaceArgUses(Arg);
669
670 // If Arg is a no-op casted pointer, strip one level of casts and iterate.
671 if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
672 Arg = BI->getOperand(0);
673 else if (isa<GEPOperator>(Arg) &&
674 cast<GEPOperator>(Arg)->hasAllZeroIndices())
675 Arg = cast<GEPOperator>(Arg)->getPointerOperand();
676 else if (isa<GlobalAlias>(Arg) &&
677 !cast<GlobalAlias>(Arg)->isInterposable())
678 Arg = cast<GlobalAlias>(Arg)->getAliasee();
679 else {
680 // If Arg is a PHI node, get PHIs that are equivalent to it and replace
681 // their uses.
682 if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
683 SmallVector<Value *, 1> PHIList;
684 getEquivalentPHIs(*PN, PHIList);
685 for (Value *PHI : PHIList)
686 ReplaceArgUses(PHI);
687 }
688 break;
689 }
690 }
691
692 // Replace bitcast users of Arg that are dominated by Inst.
693 SmallVector<BitCastInst *, 2> BitCastUsers;
694
695 // Add all bitcast users of the function argument first.
696 for (User *U : OrigArg->users())
697 if (auto *BC = dyn_cast<BitCastInst>(U))
698 BitCastUsers.push_back(BC);
699
700 // Replace the bitcasts with the call return. Iterate until list is empty.
701 while (!BitCastUsers.empty()) {
702 auto *BC = BitCastUsers.pop_back_val();
703 for (User *U : BC->users())
704 if (auto *B = dyn_cast<BitCastInst>(U))
705 BitCastUsers.push_back(B);
706
707 ReplaceArgUses(BC);
708 }
709 }
710
711 // If this function has no escaping allocas or suspicious vararg usage,
712 // objc_storeStrong calls can be marked with the "tail" keyword.
713 if (TailOkForStoreStrongs)
714 for (CallInst *CI : StoreStrongCalls)
715 CI->setTailCall();
716 StoreStrongCalls.clear();
717
718 return Changed;
719 }
720
721 //===----------------------------------------------------------------------===//
722 // Misc Pass Manager
723 //===----------------------------------------------------------------------===//
724
725 char ObjCARCContractLegacyPass::ID = 0;
726 INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
727 "ObjC ARC contraction", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)728 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
729 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
730 INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
731 "ObjC ARC contraction", false, false)
732
733 void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
734 AU.addRequired<AAResultsWrapperPass>();
735 AU.addRequired<DominatorTreeWrapperPass>();
736 AU.setPreservesCFG();
737 }
738
createObjCARCContractPass()739 Pass *llvm::createObjCARCContractPass() {
740 return new ObjCARCContractLegacyPass();
741 }
742
doInitialization(Module & M)743 bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
744 return OCARCC.init(M);
745 }
746
runOnFunction(Function & F)747 bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
748 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
749 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
750 return OCARCC.run(F, AA, DT);
751 }
752
run(Function & F,FunctionAnalysisManager & AM)753 PreservedAnalyses ObjCARCContractPass::run(Function &F,
754 FunctionAnalysisManager &AM) {
755 ObjCARCContract OCAC;
756 OCAC.init(*F.getParent());
757
758 bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
759 &AM.getResult<DominatorTreeAnalysis>(F));
760 if (Changed) {
761 PreservedAnalyses PA;
762 PA.preserveSet<CFGAnalyses>();
763 return PA;
764 }
765 return PreservedAnalyses::all();
766 }
767