blob: fe6406a0354193bbeb28b58d7731fdd4627964f1 [file] [log] [blame]
Michael Gottesmanfa0939f2013-01-28 04:12:07 +00001//===- ObjCARCOpts.cpp - ObjC ARC Optimization ----------------------------===//
2//
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 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///
14/// The optimizations performed include elimination of redundant, partially
15/// redundant, and inconsequential reference count operations, elimination of
16/// redundant weak pointer operations, pattern-matching and replacement of
17/// low-level operations into higher-level operations, and numerous minor
18/// simplifications.
19///
20/// This file also defines a simple ARC-aware AliasAnalysis.
21///
22/// WARNING: This file knows about certain library functions. It recognizes them
23/// by name, and hardwires knowledge of their semantics.
24///
25/// WARNING: This file knows about how certain Objective-C library functions are
26/// used. Naive LLVM IR transformations which would otherwise be
27/// behavior-preserving may break these assumptions.
28///
29//===----------------------------------------------------------------------===//
30
31#define DEBUG_TYPE "objc-arc-ap-elim"
32#include "ObjCARC.h"
Michael Gottesmanfa0939f2013-01-28 04:12:07 +000033#include "llvm/ADT/STLExtras.h"
34#include "llvm/IR/Constants.h"
35
36using namespace llvm;
37using namespace llvm::objcarc;
38
39namespace {
40 /// \brief Autorelease pool elimination.
41 class ObjCARCAPElim : public ModulePass {
42 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
43 virtual bool runOnModule(Module &M);
44
45 static bool MayAutorelease(ImmutableCallSite CS, unsigned Depth = 0);
46 static bool OptimizeBB(BasicBlock *BB);
47
48 public:
49 static char ID;
50 ObjCARCAPElim() : ModulePass(ID) {
51 initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry());
52 }
53 };
54}
55
56char ObjCARCAPElim::ID = 0;
57INITIALIZE_PASS(ObjCARCAPElim,
58 "objc-arc-apelim",
59 "ObjC ARC autorelease pool elimination",
60 false, false)
61
62Pass *llvm::createObjCARCAPElimPass() {
63 return new ObjCARCAPElim();
64}
65
66void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const {
67 AU.setPreservesCFG();
68}
69
70/// Interprocedurally determine if calls made by the given call site can
71/// possibly produce autoreleases.
72bool ObjCARCAPElim::MayAutorelease(ImmutableCallSite CS, unsigned Depth) {
73 if (const Function *Callee = CS.getCalledFunction()) {
74 if (Callee->isDeclaration() || Callee->mayBeOverridden())
75 return true;
76 for (Function::const_iterator I = Callee->begin(), E = Callee->end();
77 I != E; ++I) {
78 const BasicBlock *BB = I;
79 for (BasicBlock::const_iterator J = BB->begin(), F = BB->end();
80 J != F; ++J)
81 if (ImmutableCallSite JCS = ImmutableCallSite(J))
82 // This recursion depth limit is arbitrary. It's just great
83 // enough to cover known interesting testcases.
84 if (Depth < 3 &&
85 !JCS.onlyReadsMemory() &&
86 MayAutorelease(JCS, Depth + 1))
87 return true;
88 }
89 return false;
90 }
91
92 return true;
93}
94
95bool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) {
96 bool Changed = false;
97
98 Instruction *Push = 0;
99 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
100 Instruction *Inst = I++;
101 switch (GetBasicInstructionClass(Inst)) {
102 case IC_AutoreleasepoolPush:
103 Push = Inst;
104 break;
105 case IC_AutoreleasepoolPop:
106 // If this pop matches a push and nothing in between can autorelease,
107 // zap the pair.
108 if (Push && cast<CallInst>(Inst)->getArgOperand(0) == Push) {
109 Changed = true;
110 DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop "
111 "autorelease pair:\n"
112 " Pop: " << *Inst << "\n"
113 << " Push: " << *Push << "\n");
114 Inst->eraseFromParent();
115 Push->eraseFromParent();
116 }
117 Push = 0;
118 break;
119 case IC_CallOrUser:
120 if (MayAutorelease(ImmutableCallSite(Inst)))
121 Push = 0;
122 break;
123 default:
124 break;
125 }
126 }
127
128 return Changed;
129}
130
131bool ObjCARCAPElim::runOnModule(Module &M) {
132 if (!EnableARCOpts)
133 return false;
134
135 // If nothing in the Module uses ARC, don't do anything.
136 if (!ModuleHasARC(M))
137 return false;
138
139 // Find the llvm.global_ctors variable, as the first step in
140 // identifying the global constructors. In theory, unnecessary autorelease
141 // pools could occur anywhere, but in practice it's pretty rare. Global
142 // ctors are a place where autorelease pools get inserted automatically,
143 // so it's pretty common for them to be unnecessary, and it's pretty
144 // profitable to eliminate them.
145 GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
146 if (!GV)
147 return false;
148
149 assert(GV->hasDefinitiveInitializer() &&
150 "llvm.global_ctors is uncooperative!");
151
152 bool Changed = false;
153
154 // Dig the constructor functions out of GV's initializer.
155 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
156 for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end();
157 OI != OE; ++OI) {
158 Value *Op = *OI;
159 // llvm.global_ctors is an array of pairs where the second members
160 // are constructor functions.
161 Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1));
162 // If the user used a constructor function with the wrong signature and
163 // it got bitcasted or whatever, look the other way.
164 if (!F)
165 continue;
166 // Only look at function definitions.
167 if (F->isDeclaration())
168 continue;
169 // Only look at functions with one basic block.
170 if (llvm::next(F->begin()) != F->end())
171 continue;
172 // Ok, a single-block constructor function definition. Try to optimize it.
173 Changed |= OptimizeBB(F->begin());
174 }
175
176 return Changed;
177}