blob: bab2d1c585d36707491acee070f262d98d794774 [file] [log] [blame]
Michael Gottesman1e29ca12013-01-29 05:07:18 +00001//===- ObjCARCContract.cpp - ObjC ARC Optimization ------------------------===//
Michael Gottesman778138e2013-01-29 03:03:03 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file defines late ObjC ARC optimizations. ARC stands for Automatic
11/// Reference Counting and is a system for managing reference counts for objects
12/// in Objective C.
13///
Michael Gottesman697d8b92013-02-07 04:12:57 +000014/// This specific file mainly deals with ``contracting'' multiple lower level
15/// operations into singular higher level operations through pattern matching.
16///
Michael Gottesman778138e2013-01-29 03:03:03 +000017/// WARNING: This file knows about certain library functions. It recognizes them
18/// by name, and hardwires knowledge of their semantics.
19///
20/// WARNING: This file knows about how certain Objective-C library functions are
21/// used. Naive LLVM IR transformations which would otherwise be
22/// behavior-preserving may break these assumptions.
23///
24//===----------------------------------------------------------------------===//
25
26// TODO: ObjCARCContract could insert PHI nodes when uses aren't
27// dominated by single calls.
28
Michael Gottesman0b912b22013-07-06 01:39:26 +000029#include "ARCRuntimeEntryPoints.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000030#include "DependencyAnalysis.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000031#include "ObjCARC.h"
Michael Gottesman278266f2013-01-29 04:20:52 +000032#include "ProvenanceAnalysis.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000033#include "llvm/ADT/Statistic.h"
Shoaib Meenai3f689c82018-03-20 20:45:41 +000034#include "llvm/Analysis/EHPersonalities.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000035#include "llvm/IR/Dominators.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000036#include "llvm/IR/InlineAsm.h"
37#include "llvm/IR/Operator.h"
Michael Gottesman13a5f1a2013-01-29 04:51:59 +000038#include "llvm/Support/Debug.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000039#include "llvm/Support/raw_ostream.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000040
41using namespace llvm;
42using namespace llvm::objcarc;
43
Chandler Carruth964daaa2014-04-22 02:55:47 +000044#define DEBUG_TYPE "objc-arc-contract"
45
Michael Gottesman778138e2013-01-29 03:03:03 +000046STATISTIC(NumPeeps, "Number of calls peephole-optimized");
47STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
48
Michael Gottesman56bd6a02015-02-19 00:42:27 +000049//===----------------------------------------------------------------------===//
50// Declarations
51//===----------------------------------------------------------------------===//
52
Michael Gottesman778138e2013-01-29 03:03:03 +000053namespace {
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000054 /// Late ARC optimizations
Michael Gottesman778138e2013-01-29 03:03:03 +000055 ///
56 /// These change the IR in a way that makes it difficult to be analyzed by
57 /// ObjCARCOpt, so it's run late.
58 class ObjCARCContract : public FunctionPass {
59 bool Changed;
60 AliasAnalysis *AA;
61 DominatorTree *DT;
62 ProvenanceAnalysis PA;
Michael Gottesman0b912b22013-07-06 01:39:26 +000063 ARCRuntimeEntryPoints EP;
Michael Gottesman778138e2013-01-29 03:03:03 +000064
65 /// A flag indicating whether this optimization pass should run.
66 bool Run;
67
Michael Gottesman778138e2013-01-29 03:03:03 +000068 /// The inline asm string to insert between calls and RetainRV calls to make
69 /// the optimization work on targets which need it.
John McCall3fe604f2016-01-27 19:05:08 +000070 const MDString *RVInstMarker;
Michael Gottesman778138e2013-01-29 03:03:03 +000071
72 /// The set of inserted objc_storeStrong calls. If at the end of walking the
73 /// function we have found no alloca instructions, these calls can be marked
74 /// "tail".
75 SmallPtrSet<CallInst *, 8> StoreStrongCalls;
76
Michael Gottesman18279732015-02-19 00:42:30 +000077 /// Returns true if we eliminated Inst.
Shoaib Meenai106df7d2018-04-20 22:14:45 +000078 bool tryToPeepholeInstruction(
79 Function &F, Instruction *Inst, inst_iterator &Iter,
80 SmallPtrSetImpl<Instruction *> &DepInsts,
81 SmallPtrSetImpl<const BasicBlock *> &Visited,
82 bool &TailOkForStoreStrong,
83 const DenseMap<BasicBlock *, ColorVector> &BlockColors);
Michael Gottesman18279732015-02-19 00:42:30 +000084
Michael Gottesman56bd6a02015-02-19 00:42:27 +000085 bool optimizeRetainCall(Function &F, Instruction *Retain);
Michael Gottesman214ca902013-04-29 06:53:53 +000086
Michael Gottesman56bd6a02015-02-19 00:42:27 +000087 bool
88 contractAutorelease(Function &F, Instruction *Autorelease,
Michael Gottesman6f729fa2015-02-19 19:51:32 +000089 ARCInstKind Class,
Michael Gottesman56bd6a02015-02-19 00:42:27 +000090 SmallPtrSetImpl<Instruction *> &DependingInstructions,
91 SmallPtrSetImpl<const BasicBlock *> &Visited);
Michael Gottesman778138e2013-01-29 03:03:03 +000092
Shoaib Meenaid64b8322018-04-20 22:11:03 +000093 void tryToContractReleaseIntoStoreStrong(
94 Instruction *Release, inst_iterator &Iter,
95 const DenseMap<BasicBlock *, ColorVector> &BlockColors);
Michael Gottesman778138e2013-01-29 03:03:03 +000096
Craig Topper3e4c6972014-03-05 09:10:37 +000097 void getAnalysisUsage(AnalysisUsage &AU) const override;
98 bool doInitialization(Module &M) override;
99 bool runOnFunction(Function &F) override;
Michael Gottesman778138e2013-01-29 03:03:03 +0000100
101 public:
102 static char ID;
103 ObjCARCContract() : FunctionPass(ID) {
104 initializeObjCARCContractPass(*PassRegistry::getPassRegistry());
105 }
106 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000107}
Michael Gottesman778138e2013-01-29 03:03:03 +0000108
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000109//===----------------------------------------------------------------------===//
110// Implementation
111//===----------------------------------------------------------------------===//
Michael Gottesman778138e2013-01-29 03:03:03 +0000112
Michael Gottesman214ca902013-04-29 06:53:53 +0000113/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
114/// return value. We do this late so we do not disrupt the dataflow analysis in
115/// ObjCARCOpt.
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000116bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000117 ImmutableCallSite CS(GetArgRCIdentityRoot(Retain));
Michael Gottesman214ca902013-04-29 06:53:53 +0000118 const Instruction *Call = CS.getInstruction();
119 if (!Call)
120 return false;
121 if (Call->getParent() != Retain->getParent())
122 return false;
123
124 // Check that the call is next to the retain.
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000125 BasicBlock::const_iterator I = ++Call->getIterator();
126 while (IsNoopInstruction(&*I))
127 ++I;
Michael Gottesman214ca902013-04-29 06:53:53 +0000128 if (&*I != Retain)
129 return false;
130
131 // Turn it to an objc_retainAutoreleasedReturnValue.
132 Changed = true;
133 ++NumPeeps;
134
135 DEBUG(dbgs() << "Transforming objc_retain => "
136 "objc_retainAutoreleasedReturnValue since the operand is a "
137 "return value.\nOld: "<< *Retain << "\n");
138
139 // We do not have to worry about tail calls/does not throw since
140 // retain/retainRV have the same properties.
Michael Gottesmanca3a4722015-03-16 07:02:24 +0000141 Constant *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV);
Michael Gottesman0b912b22013-07-06 01:39:26 +0000142 cast<CallInst>(Retain)->setCalledFunction(Decl);
Michael Gottesman214ca902013-04-29 06:53:53 +0000143
144 DEBUG(dbgs() << "New: " << *Retain << "\n");
145 return true;
146}
147
Michael Gottesman778138e2013-01-29 03:03:03 +0000148/// Merge an autorelease with a retain into a fused call.
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000149bool ObjCARCContract::contractAutorelease(
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000150 Function &F, Instruction *Autorelease, ARCInstKind Class,
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000151 SmallPtrSetImpl<Instruction *> &DependingInstructions,
152 SmallPtrSetImpl<const BasicBlock *> &Visited) {
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000153 const Value *Arg = GetArgRCIdentityRoot(Autorelease);
Michael Gottesman778138e2013-01-29 03:03:03 +0000154
155 // Check that there are no instructions between the retain and the autorelease
156 // (such as an autorelease_pop) which may change the count.
Craig Topperf40110f2014-04-25 05:29:35 +0000157 CallInst *Retain = nullptr;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000158 if (Class == ARCInstKind::AutoreleaseRV)
Michael Gottesman778138e2013-01-29 03:03:03 +0000159 FindDependencies(RetainAutoreleaseRVDep, Arg,
160 Autorelease->getParent(), Autorelease,
161 DependingInstructions, Visited, PA);
162 else
163 FindDependencies(RetainAutoreleaseDep, Arg,
164 Autorelease->getParent(), Autorelease,
165 DependingInstructions, Visited, PA);
166
167 Visited.clear();
168 if (DependingInstructions.size() != 1) {
169 DependingInstructions.clear();
170 return false;
171 }
172
173 Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
174 DependingInstructions.clear();
175
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000176 if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000177 GetArgRCIdentityRoot(Retain) != Arg)
Michael Gottesman778138e2013-01-29 03:03:03 +0000178 return false;
179
180 Changed = true;
181 ++NumPeeps;
182
Michael Gottesman18279732015-02-19 00:42:30 +0000183 DEBUG(dbgs() << " Fusing retain/autorelease!\n"
184 " Autorelease:" << *Autorelease << "\n"
185 " Retain: " << *Retain << "\n");
Michael Gottesman778138e2013-01-29 03:03:03 +0000186
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000187 Constant *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
Michael Gottesmanca3a4722015-03-16 07:02:24 +0000188 ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV
189 : ARCRuntimeEntryPointKind::RetainAutorelease);
Michael Gottesman0b912b22013-07-06 01:39:26 +0000190 Retain->setCalledFunction(Decl);
Michael Gottesman778138e2013-01-29 03:03:03 +0000191
Michael Gottesman18279732015-02-19 00:42:30 +0000192 DEBUG(dbgs() << " New RetainAutorelease: " << *Retain << "\n");
Michael Gottesman778138e2013-01-29 03:03:03 +0000193
194 EraseInstruction(Autorelease);
195 return true;
196}
197
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000198static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
199 Instruction *Release,
200 ProvenanceAnalysis &PA,
201 AliasAnalysis *AA) {
Craig Topperf40110f2014-04-25 05:29:35 +0000202 StoreInst *Store = nullptr;
Michael Gottesman778138e2013-01-29 03:03:03 +0000203 bool SawRelease = false;
Michael Gottesman778138e2013-01-29 03:03:03 +0000204
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000205 // Get the location associated with Load.
Chandler Carruthac80dc72015-06-17 07:18:54 +0000206 MemoryLocation Loc = MemoryLocation::get(Load);
Pete Cooper1929b552016-05-27 02:13:53 +0000207 auto *LocPtr = Loc.Ptr->stripPointerCasts();
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000208
209 // Walk down to find the store and the release, which may be in either order.
210 for (auto I = std::next(BasicBlock::iterator(Load)),
211 E = Load->getParent()->end();
212 I != E; ++I) {
213 // If we found the store we were looking for and saw the release,
214 // break. There is no more work to be done.
215 if (Store && SawRelease)
216 break;
217
218 // Now we know that we have not seen either the store or the release. If I
Eric Christopher572e03a2015-06-19 01:53:21 +0000219 // is the release, mark that we saw the release and continue.
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000220 Instruction *Inst = &*I;
Michael Gottesman778138e2013-01-29 03:03:03 +0000221 if (Inst == Release) {
222 SawRelease = true;
223 continue;
224 }
225
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000226 // Otherwise, we check if Inst is a "good" store. Grab the instruction class
227 // of Inst.
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000228 ARCInstKind Class = GetBasicARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000229
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000230 // If Inst is an unrelated retain, we don't care about it.
231 //
232 // TODO: This is one area where the optimization could be made more
233 // aggressive.
Michael Gottesman778138e2013-01-29 03:03:03 +0000234 if (IsRetain(Class))
235 continue;
236
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000237 // If we have seen the store, but not the release...
Michael Gottesman778138e2013-01-29 03:03:03 +0000238 if (Store) {
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000239 // We need to make sure that it is safe to move the release from its
240 // current position to the store. This implies proving that any
241 // instruction in between Store and the Release conservatively can not use
242 // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
243 // continue...
244 if (!CanUse(Inst, Load, PA, Class)) {
245 continue;
246 }
247
248 // Otherwise, be conservative and return nullptr.
249 return nullptr;
Michael Gottesman778138e2013-01-29 03:03:03 +0000250 }
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000251
252 // Ok, now we know we have not seen a store yet. See if Inst can write to
253 // our load location, if it can not, just ignore the instruction.
Alina Sbirlea63d22502017-12-05 20:12:23 +0000254 if (!isModSet(AA->getModRefInfo(Inst, Loc)))
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000255 continue;
256
257 Store = dyn_cast<StoreInst>(Inst);
258
259 // If Inst can, then check if Inst is a simple store. If Inst is not a
260 // store or a store that is not simple, then we have some we do not
261 // understand writing to this memory implying we can not move the load
262 // over the write to any subsequent store that we may find.
263 if (!Store || !Store->isSimple())
264 return nullptr;
265
266 // Then make sure that the pointer we are storing to is Ptr. If so, we
267 // found our Store!
Pete Cooper1929b552016-05-27 02:13:53 +0000268 if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000269 continue;
270
271 // Otherwise, we have an unknown store to some other ptr that clobbers
272 // Loc.Ptr. Bail!
273 return nullptr;
Michael Gottesman778138e2013-01-29 03:03:03 +0000274 }
275
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000276 // If we did not find the store or did not see the release, fail.
277 if (!Store || !SawRelease)
278 return nullptr;
Michael Gottesman778138e2013-01-29 03:03:03 +0000279
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000280 // We succeeded!
281 return Store;
282}
283
284static Instruction *
285findRetainForStoreStrongContraction(Value *New, StoreInst *Store,
286 Instruction *Release,
287 ProvenanceAnalysis &PA) {
288 // Walk up from the Store to find the retain.
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000289 BasicBlock::iterator I = Store->getIterator();
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000290 BasicBlock::iterator Begin = Store->getParent()->begin();
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000291 while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000292 Instruction *Inst = &*I;
293
294 // It is only safe to move the retain to the store if we can prove
295 // conservatively that nothing besides the release can decrement reference
296 // counts in between the retain and the store.
297 if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
298 return nullptr;
Michael Gottesman778138e2013-01-29 03:03:03 +0000299 --I;
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000300 }
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000301 Instruction *Retain = &*I;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000302 if (GetBasicARCInstKind(Retain) != ARCInstKind::Retain)
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000303 return nullptr;
304 if (GetArgRCIdentityRoot(Retain) != New)
305 return nullptr;
306 return Retain;
307}
308
Shoaib Meenaid64b8322018-04-20 22:11:03 +0000309/// Create a call instruction with the correct funclet token. Should be used
310/// instead of calling CallInst::Create directly.
311static CallInst *
312createCallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr,
313 Instruction *InsertBefore,
314 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
315 SmallVector<OperandBundleDef, 1> OpBundles;
316 if (!BlockColors.empty()) {
317 const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
318 assert(CV.size() == 1 && "non-unique color for block!");
319 Instruction *EHPad = CV.front()->getFirstNonPHI();
320 if (EHPad->isEHPad())
321 OpBundles.emplace_back("funclet", EHPad);
322 }
323
324 return CallInst::Create(Func, Args, OpBundles, NameStr, InsertBefore);
325}
326
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000327/// Attempt to merge an objc_release with a store, load, and objc_retain to form
328/// an objc_storeStrong. An objc_storeStrong:
329///
330/// objc_storeStrong(i8** %old_ptr, i8* new_value)
331///
332/// is equivalent to the following IR sequence:
333///
334/// ; Load old value.
335/// %old_value = load i8** %old_ptr (1)
336///
337/// ; Increment the new value and then release the old value. This must occur
338/// ; in order in case old_value releases new_value in its destructor causing
339/// ; us to potentially have a dangling ptr.
340/// tail call i8* @objc_retain(i8* %new_value) (2)
341/// tail call void @objc_release(i8* %old_value) (3)
342///
343/// ; Store the new_value into old_ptr
344/// store i8* %new_value, i8** %old_ptr (4)
345///
346/// The safety of this optimization is based around the following
347/// considerations:
348///
349/// 1. We are forming the store strong at the store. Thus to perform this
350/// optimization it must be safe to move the retain, load, and release to
351/// (4).
352/// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
353/// safe.
Shoaib Meenaid64b8322018-04-20 22:11:03 +0000354void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
355 Instruction *Release, inst_iterator &Iter,
356 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000357 // See if we are releasing something that we just loaded.
358 auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
359 if (!Load || !Load->isSimple())
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000360 return;
Michael Gottesman0fc2acc2015-02-20 00:02:49 +0000361
362 // For now, require everything to be in one basic block.
363 BasicBlock *BB = Release->getParent();
364 if (Load->getParent() != BB)
365 return;
366
367 // First scan down the BB from Load, looking for a store of the RCIdentityRoot
368 // of Load's
369 StoreInst *Store =
370 findSafeStoreForStoreStrongContraction(Load, Release, PA, AA);
371 // If we fail, bail.
372 if (!Store)
373 return;
374
375 // Then find what new_value's RCIdentity Root is.
376 Value *New = GetRCIdentityRoot(Store->getValueOperand());
377
378 // Then walk up the BB and look for a retain on New without any intervening
379 // instructions which conservatively might decrement ref counts.
380 Instruction *Retain =
381 findRetainForStoreStrongContraction(New, Store, Release, PA);
382
383 // If we fail, bail.
384 if (!Retain)
385 return;
Michael Gottesman778138e2013-01-29 03:03:03 +0000386
387 Changed = true;
388 ++NumStoreStrongs;
389
Michael Gottesman18279732015-02-19 00:42:30 +0000390 DEBUG(
391 llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n"
392 << " Old:\n"
393 << " Store: " << *Store << "\n"
394 << " Release: " << *Release << "\n"
395 << " Retain: " << *Retain << "\n"
396 << " Load: " << *Load << "\n");
397
Michael Gottesman778138e2013-01-29 03:03:03 +0000398 LLVMContext &C = Release->getContext();
399 Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
400 Type *I8XX = PointerType::getUnqual(I8X);
401
402 Value *Args[] = { Load->getPointerOperand(), New };
403 if (Args[0]->getType() != I8XX)
404 Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
405 if (Args[1]->getType() != I8X)
406 Args[1] = new BitCastInst(Args[1], I8X, "", Store);
Michael Gottesmanca3a4722015-03-16 07:02:24 +0000407 Constant *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
Shoaib Meenaid64b8322018-04-20 22:11:03 +0000408 CallInst *StoreStrong = createCallInst(Decl, Args, "", Store, BlockColors);
Michael Gottesman778138e2013-01-29 03:03:03 +0000409 StoreStrong->setDoesNotThrow();
410 StoreStrong->setDebugLoc(Store->getDebugLoc());
411
412 // We can't set the tail flag yet, because we haven't yet determined
413 // whether there are any escaping allocas. Remember this call, so that
414 // we can set the tail flag once we know it's safe.
415 StoreStrongCalls.insert(StoreStrong);
416
Michael Gottesman18279732015-02-19 00:42:30 +0000417 DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong << "\n");
418
Akira Hatanaka75be84f2017-04-05 03:44:09 +0000419 if (&*Iter == Retain) ++Iter;
Michael Gottesman778138e2013-01-29 03:03:03 +0000420 if (&*Iter == Store) ++Iter;
421 Store->eraseFromParent();
422 Release->eraseFromParent();
423 EraseInstruction(Retain);
424 if (Load->use_empty())
425 Load->eraseFromParent();
426}
427
Michael Gottesman18279732015-02-19 00:42:30 +0000428bool ObjCARCContract::tryToPeepholeInstruction(
429 Function &F, Instruction *Inst, inst_iterator &Iter,
430 SmallPtrSetImpl<Instruction *> &DependingInsts,
431 SmallPtrSetImpl<const BasicBlock *> &Visited,
Shoaib Meenai3f689c82018-03-20 20:45:41 +0000432 bool &TailOkForStoreStrongs,
Shoaib Meenai106df7d2018-04-20 22:14:45 +0000433 const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
Michael Gottesman778138e2013-01-29 03:03:03 +0000434 // Only these library routines return their argument. In particular,
435 // objc_retainBlock does not necessarily return its argument.
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000436 ARCInstKind Class = GetBasicARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000437 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000438 case ARCInstKind::FusedRetainAutorelease:
439 case ARCInstKind::FusedRetainAutoreleaseRV:
Michael Gottesman18279732015-02-19 00:42:30 +0000440 return false;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000441 case ARCInstKind::Autorelease:
442 case ARCInstKind::AutoreleaseRV:
Michael Gottesman18279732015-02-19 00:42:30 +0000443 return contractAutorelease(F, Inst, Class, DependingInsts, Visited);
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000444 case ARCInstKind::Retain:
Michael Gottesman214ca902013-04-29 06:53:53 +0000445 // Attempt to convert retains to retainrvs if they are next to function
446 // calls.
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000447 if (!optimizeRetainCall(F, Inst))
Michael Gottesman18279732015-02-19 00:42:30 +0000448 return false;
Michael Gottesman214ca902013-04-29 06:53:53 +0000449 // If we succeed in our optimization, fall through.
Justin Bognerb03fd122016-08-17 05:10:15 +0000450 LLVM_FALLTHROUGH;
John McCall3fe604f2016-01-27 19:05:08 +0000451 case ARCInstKind::RetainRV:
452 case ARCInstKind::ClaimRV: {
Michael Gottesman778138e2013-01-29 03:03:03 +0000453 // If we're compiling for a target which needs a special inline-asm
John McCall3fe604f2016-01-27 19:05:08 +0000454 // marker to do the return value optimization, insert it now.
455 if (!RVInstMarker)
Michael Gottesman18279732015-02-19 00:42:30 +0000456 return false;
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000457 BasicBlock::iterator BBI = Inst->getIterator();
Michael Gottesman778138e2013-01-29 03:03:03 +0000458 BasicBlock *InstParent = Inst->getParent();
459
John McCall3fe604f2016-01-27 19:05:08 +0000460 // Step up to see if the call immediately precedes the RV call.
Michael Gottesman778138e2013-01-29 03:03:03 +0000461 // If it's an invoke, we have to cross a block boundary. And we have
462 // to carefully dodge no-op instructions.
463 do {
Duncan P. N. Exon Smithe9bc5792016-02-21 20:39:50 +0000464 if (BBI == InstParent->begin()) {
Michael Gottesman778138e2013-01-29 03:03:03 +0000465 BasicBlock *Pred = InstParent->getSinglePredecessor();
466 if (!Pred)
467 goto decline_rv_optimization;
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000468 BBI = Pred->getTerminator()->getIterator();
Michael Gottesman778138e2013-01-29 03:03:03 +0000469 break;
470 }
471 --BBI;
Duncan P. N. Exon Smith1e59a662015-10-19 23:20:14 +0000472 } while (IsNoopInstruction(&*BBI));
Michael Gottesman778138e2013-01-29 03:03:03 +0000473
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000474 if (&*BBI == GetArgRCIdentityRoot(Inst)) {
John McCall3fe604f2016-01-27 19:05:08 +0000475 DEBUG(dbgs() << "Adding inline asm marker for the return value "
476 "optimization.\n");
Michael Gottesman778138e2013-01-29 03:03:03 +0000477 Changed = true;
John McCall3fe604f2016-01-27 19:05:08 +0000478 InlineAsm *IA = InlineAsm::get(
479 FunctionType::get(Type::getVoidTy(Inst->getContext()),
480 /*isVarArg=*/false),
481 RVInstMarker->getString(),
482 /*Constraints=*/"", /*hasSideEffects=*/true);
Shoaib Meenai3f689c82018-03-20 20:45:41 +0000483
Shoaib Meenaid64b8322018-04-20 22:11:03 +0000484 createCallInst(IA, None, "", Inst, BlockColors);
Michael Gottesman778138e2013-01-29 03:03:03 +0000485 }
486 decline_rv_optimization:
Michael Gottesman18279732015-02-19 00:42:30 +0000487 return false;
Michael Gottesman778138e2013-01-29 03:03:03 +0000488 }
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000489 case ARCInstKind::InitWeak: {
Michael Gottesman778138e2013-01-29 03:03:03 +0000490 // objc_initWeak(p, null) => *p = null
491 CallInst *CI = cast<CallInst>(Inst);
Michael Gottesman65c24812013-03-25 09:27:43 +0000492 if (IsNullOrUndef(CI->getArgOperand(1))) {
Michael Gottesman778138e2013-01-29 03:03:03 +0000493 Value *Null =
494 ConstantPointerNull::get(cast<PointerType>(CI->getType()));
495 Changed = true;
496 new StoreInst(Null, CI->getArgOperand(0), CI);
497
498 DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
499 << " New = " << *Null << "\n");
500
501 CI->replaceAllUsesWith(Null);
502 CI->eraseFromParent();
503 }
Michael Gottesman18279732015-02-19 00:42:30 +0000504 return true;
Michael Gottesman778138e2013-01-29 03:03:03 +0000505 }
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000506 case ARCInstKind::Release:
Michael Gottesmandfa3e4b2015-02-19 00:42:34 +0000507 // Try to form an objc store strong from our release. If we fail, there is
508 // nothing further to do below, so continue.
Shoaib Meenaid64b8322018-04-20 22:11:03 +0000509 tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
Michael Gottesman18279732015-02-19 00:42:30 +0000510 return true;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000511 case ARCInstKind::User:
Michael Gottesman778138e2013-01-29 03:03:03 +0000512 // Be conservative if the function has any alloca instructions.
513 // Technically we only care about escaping alloca instructions,
514 // but this is sufficient to handle some interesting cases.
515 if (isa<AllocaInst>(Inst))
516 TailOkForStoreStrongs = false;
Michael Gottesman18279732015-02-19 00:42:30 +0000517 return true;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000518 case ARCInstKind::IntrinsicUser:
John McCall20182ac2013-03-22 21:38:36 +0000519 // Remove calls to @clang.arc.use(...).
520 Inst->eraseFromParent();
Michael Gottesman18279732015-02-19 00:42:30 +0000521 return true;
Michael Gottesman778138e2013-01-29 03:03:03 +0000522 default:
Michael Gottesman18279732015-02-19 00:42:30 +0000523 return true;
Michael Gottesman778138e2013-01-29 03:03:03 +0000524 }
Michael Gottesman18279732015-02-19 00:42:30 +0000525}
Michael Gottesman778138e2013-01-29 03:03:03 +0000526
Michael Gottesman18279732015-02-19 00:42:30 +0000527//===----------------------------------------------------------------------===//
528// Top Level Driver
529//===----------------------------------------------------------------------===//
530
531bool ObjCARCContract::runOnFunction(Function &F) {
532 if (!EnableARCOpts)
533 return false;
534
535 // If nothing in the Module uses ARC, don't do anything.
536 if (!Run)
537 return false;
538
539 Changed = false;
Chandler Carruth7b560d42015-09-09 17:55:00 +0000540 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
Michael Gottesman18279732015-02-19 00:42:30 +0000541 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
542
Chandler Carruth7b560d42015-09-09 17:55:00 +0000543 PA.setAA(&getAnalysis<AAResultsWrapperPass>().getAAResults());
Michael Gottesman18279732015-02-19 00:42:30 +0000544
Shoaib Meenai3f689c82018-03-20 20:45:41 +0000545 DenseMap<BasicBlock *, ColorVector> BlockColors;
546 if (F.hasPersonalityFn() &&
547 isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
548 BlockColors = colorEHFunclets(F);
549
Michael Gottesman18279732015-02-19 00:42:30 +0000550 DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
551
552 // Track whether it's ok to mark objc_storeStrong calls with the "tail"
553 // keyword. Be conservative if the function has variadic arguments.
554 // It seems that functions which "return twice" are also unsafe for the
555 // "tail" argument, because they are setjmp, which could need to
556 // return to an earlier stack state.
557 bool TailOkForStoreStrongs =
558 !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
559
560 // For ObjC library calls which return their argument, replace uses of the
561 // argument with uses of the call return value, if it dominates the use. This
562 // reduces register pressure.
563 SmallPtrSet<Instruction *, 4> DependingInstructions;
564 SmallPtrSet<const BasicBlock *, 4> Visited;
565 for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
566 Instruction *Inst = &*I++;
567
568 DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
569
570 // First try to peephole Inst. If there is nothing further we can do in
571 // terms of undoing objc-arc-expand, process the next inst.
572 if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited,
Shoaib Meenai3f689c82018-03-20 20:45:41 +0000573 TailOkForStoreStrongs, BlockColors))
Michael Gottesman18279732015-02-19 00:42:30 +0000574 continue;
575
576 // Otherwise, try to undo objc-arc-expand.
Michael Gottesman778138e2013-01-29 03:03:03 +0000577
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000578 // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
Michael Gottesman778138e2013-01-29 03:03:03 +0000579 // and such; to do the replacement, the argument must have type i8*.
Michael Gottesman18279732015-02-19 00:42:30 +0000580
Akira Hatanakadea090e2016-09-13 23:43:11 +0000581 // Function for replacing uses of Arg dominated by Inst.
582 auto ReplaceArgUses = [Inst, this](Value *Arg) {
Michael Gottesman778138e2013-01-29 03:03:03 +0000583 // If we're compiling bugpointed code, don't get in trouble.
584 if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
Akira Hatanakadea090e2016-09-13 23:43:11 +0000585 return;
586
Michael Gottesman778138e2013-01-29 03:03:03 +0000587 // Look through the uses of the pointer.
Chandler Carruthcdf47882014-03-09 03:16:01 +0000588 for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
Michael Gottesman778138e2013-01-29 03:03:03 +0000589 UI != UE; ) {
Chandler Carruthcdf47882014-03-09 03:16:01 +0000590 // Increment UI now, because we may unlink its element.
591 Use &U = *UI++;
592 unsigned OperandNo = U.getOperandNo();
Michael Gottesman778138e2013-01-29 03:03:03 +0000593
594 // If the call's return value dominates a use of the call's argument
595 // value, rewrite the use to use the return value. We check for
596 // reachability here because an unreachable call is considered to
597 // trivially dominate itself, which would lead us to rewriting its
598 // argument in terms of its return value, which would lead to
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000599 // infinite loops in GetArgRCIdentityRoot.
Shoaib Meenaia07295f2018-05-03 01:20:36 +0000600 if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
601 continue;
602
603 Changed = true;
604 Instruction *Replacement = Inst;
605 Type *UseTy = U.get()->getType();
606 if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
607 // For PHI nodes, insert the bitcast in the predecessor block.
608 unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
Shoaib Meenai57fadab2018-05-04 19:03:11 +0000609 BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
610 if (Replacement->getType() != UseTy) {
611 // A catchswitch is both a pad and a terminator, meaning a basic
612 // block with a catchswitch has no insertion point. Keep going up
613 // the dominator tree until we find a non-catchswitch.
614 BasicBlock *InsertBB = IncomingBB;
615 while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) {
616 InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
617 }
618
619 assert(DT->dominates(Inst, &InsertBB->back()) &&
620 "Invalid insertion point for bitcast");
621 Replacement =
622 new BitCastInst(Replacement, UseTy, "", &InsertBB->back());
623 }
624
Shoaib Meenaia07295f2018-05-03 01:20:36 +0000625 // While we're here, rewrite all edges for this PHI, rather
626 // than just one use at a time, to minimize the number of
627 // bitcasts we emit.
628 for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
Shoaib Meenai57fadab2018-05-04 19:03:11 +0000629 if (PHI->getIncomingBlock(i) == IncomingBB) {
Shoaib Meenaia07295f2018-05-03 01:20:36 +0000630 // Keep the UI iterator valid.
631 if (UI != UE &&
632 &PHI->getOperandUse(
633 PHINode::getOperandNumForIncomingValue(i)) == &*UI)
634 ++UI;
635 PHI->setIncomingValue(i, Replacement);
636 }
637 } else {
638 if (Replacement->getType() != UseTy)
639 Replacement = new BitCastInst(Replacement, UseTy, "",
640 cast<Instruction>(U.getUser()));
641 U.set(Replacement);
Michael Gottesman778138e2013-01-29 03:03:03 +0000642 }
643 }
Akira Hatanakadea090e2016-09-13 23:43:11 +0000644 };
645
646
Akira Hatanaka6d5a2942016-09-13 23:53:43 +0000647 Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
648 Value *OrigArg = Arg;
Akira Hatanakadea090e2016-09-13 23:43:11 +0000649
650 // TODO: Change this to a do-while.
651 for (;;) {
652 ReplaceArgUses(Arg);
Michael Gottesman778138e2013-01-29 03:03:03 +0000653
654 // If Arg is a no-op casted pointer, strip one level of casts and iterate.
655 if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
656 Arg = BI->getOperand(0);
657 else if (isa<GEPOperator>(Arg) &&
658 cast<GEPOperator>(Arg)->hasAllZeroIndices())
659 Arg = cast<GEPOperator>(Arg)->getPointerOperand();
660 else if (isa<GlobalAlias>(Arg) &&
Sanjoy Das5ce32722016-04-08 00:48:30 +0000661 !cast<GlobalAlias>(Arg)->isInterposable())
Michael Gottesman778138e2013-01-29 03:03:03 +0000662 Arg = cast<GlobalAlias>(Arg)->getAliasee();
Akira Hatanaka73ceb502018-01-19 23:51:13 +0000663 else {
664 // If Arg is a PHI node, get PHIs that are equivalent to it and replace
665 // their uses.
666 if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
667 SmallVector<Value *, 1> PHIList;
668 getEquivalentPHIs(*PN, PHIList);
669 for (Value *PHI : PHIList)
670 ReplaceArgUses(PHI);
671 }
Michael Gottesman778138e2013-01-29 03:03:03 +0000672 break;
Akira Hatanaka73ceb502018-01-19 23:51:13 +0000673 }
Michael Gottesman778138e2013-01-29 03:03:03 +0000674 }
Akira Hatanakadea090e2016-09-13 23:43:11 +0000675
676 // Replace bitcast users of Arg that are dominated by Inst.
677 SmallVector<BitCastInst *, 2> BitCastUsers;
678
679 // Add all bitcast users of the function argument first.
680 for (User *U : OrigArg->users())
681 if (auto *BC = dyn_cast<BitCastInst>(U))
682 BitCastUsers.push_back(BC);
683
684 // Replace the bitcasts with the call return. Iterate until list is empty.
685 while (!BitCastUsers.empty()) {
686 auto *BC = BitCastUsers.pop_back_val();
687 for (User *U : BC->users())
688 if (auto *B = dyn_cast<BitCastInst>(U))
689 BitCastUsers.push_back(B);
690
691 ReplaceArgUses(BC);
692 }
Michael Gottesman778138e2013-01-29 03:03:03 +0000693 }
694
695 // If this function has no escaping allocas or suspicious vararg usage,
696 // objc_storeStrong calls can be marked with the "tail" keyword.
697 if (TailOkForStoreStrongs)
Craig Topper46276792014-08-24 23:23:06 +0000698 for (CallInst *CI : StoreStrongCalls)
699 CI->setTailCall();
Michael Gottesman778138e2013-01-29 03:03:03 +0000700 StoreStrongCalls.clear();
701
702 return Changed;
703}
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000704
705//===----------------------------------------------------------------------===//
706// Misc Pass Manager
707//===----------------------------------------------------------------------===//
708
709char ObjCARCContract::ID = 0;
710INITIALIZE_PASS_BEGIN(ObjCARCContract, "objc-arc-contract",
711 "ObjC ARC contraction", false, false)
Chandler Carruth7b560d42015-09-09 17:55:00 +0000712INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000713INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
714INITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract",
715 "ObjC ARC contraction", false, false)
716
717void ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const {
Chandler Carruth7b560d42015-09-09 17:55:00 +0000718 AU.addRequired<AAResultsWrapperPass>();
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000719 AU.addRequired<DominatorTreeWrapperPass>();
720 AU.setPreservesCFG();
721}
722
723Pass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); }
724
725bool ObjCARCContract::doInitialization(Module &M) {
726 // If nothing in the Module uses ARC, don't do anything.
727 Run = ModuleHasARC(M);
728 if (!Run)
729 return false;
730
Michael Gottesman65cb7372015-03-16 07:02:27 +0000731 EP.init(&M);
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000732
John McCall3fe604f2016-01-27 19:05:08 +0000733 // Initialize RVInstMarker.
734 RVInstMarker = nullptr;
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000735 if (NamedMDNode *NMD =
736 M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker"))
737 if (NMD->getNumOperands() == 1) {
738 const MDNode *N = NMD->getOperand(0);
739 if (N->getNumOperands() == 1)
740 if (const MDString *S = dyn_cast<MDString>(N->getOperand(0)))
John McCall3fe604f2016-01-27 19:05:08 +0000741 RVInstMarker = S;
Michael Gottesman56bd6a02015-02-19 00:42:27 +0000742 }
743
744 return false;
745}