llvm.org GIT mirror llvm / 3c67f1c
Refactored out pass ObjCARCAPElim from ObjCARCOpts.cpp => ObjCARCAPElim.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173654 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Gottesman 7 years ago
3 changed file(s) with 183 addition(s) and 148 deletion(s). Raw diff Collapse all Expand all
11 ObjCARC.cpp
22 ObjCARCOpts.cpp
33 ObjCARCExpand.cpp
4 ObjCARCAPElim.cpp
45 )
56
67 add_dependencies(LLVMObjCARCOpts intrinsics_gen)
0 //===- ObjCARCOpts.cpp - ObjC ARC Optimization ----------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines 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 /// The optimizations performed include elimination of redundant, partially
14 /// redundant, and inconsequential reference count operations, elimination of
15 /// redundant weak pointer operations, pattern-matching and replacement of
16 /// low-level operations into higher-level operations, and numerous minor
17 /// simplifications.
18 ///
19 /// This file also defines a simple ARC-aware AliasAnalysis.
20 ///
21 /// WARNING: This file knows about certain library functions. It recognizes them
22 /// by name, and hardwires knowledge of their semantics.
23 ///
24 /// WARNING: This file knows about how certain Objective-C library functions are
25 /// used. Naive LLVM IR transformations which would otherwise be
26 /// behavior-preserving may break these assumptions.
27 ///
28 //===----------------------------------------------------------------------===//
29
30 #define DEBUG_TYPE "objc-arc-ap-elim"
31 #include "ObjCARC.h"
32
33 #include "llvm/ADT/STLExtras.h"
34 #include "llvm/IR/Constants.h"
35
36 using namespace llvm;
37 using namespace llvm::objcarc;
38
39 namespace {
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
56 char ObjCARCAPElim::ID = 0;
57 INITIALIZE_PASS(ObjCARCAPElim,
58 "objc-arc-apelim",
59 "ObjC ARC autorelease pool elimination",
60 false, false)
61
62 Pass *llvm::createObjCARCAPElimPass() {
63 return new ObjCARCAPElim();
64 }
65
66 void 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.
72 bool 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
95 bool 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(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
131 bool 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(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(cast(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 }
178
2929
3030 #define DEBUG_TYPE "objc-arc-opts"
3131 #include "ObjCARC.h"
32
3233 #include "llvm/ADT/DenseMap.h"
3334 #include "llvm/ADT/SmallPtrSet.h"
35 #include "llvm/ADT/STLExtras.h"
36
3437 using namespace llvm;
3538 using namespace llvm::objcarc;
3639
716719 // TODO: Theoretically we could check for dependencies between objc_* calls
717720 // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
718721 return AliasAnalysis::getModRefInfo(CS1, CS2);
719 }
720
721 /// @}
722 ///
723 /// \defgroup ARCAPElim ARC Autorelease Pool Elimination.
724 /// @{
725
726 #include "llvm/ADT/STLExtras.h"
727 #include "llvm/IR/Constants.h"
728
729 namespace {
730 /// \brief Autorelease pool elimination.
731 class ObjCARCAPElim : public ModulePass {
732 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
733 virtual bool runOnModule(Module &M);
734
735 static bool MayAutorelease(ImmutableCallSite CS, unsigned Depth = 0);
736 static bool OptimizeBB(BasicBlock *BB);
737
738 public:
739 static char ID;
740 ObjCARCAPElim() : ModulePass(ID) {
741 initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry());
742 }
743 };
744 }
745
746 char ObjCARCAPElim::ID = 0;
747 INITIALIZE_PASS(ObjCARCAPElim,
748 "objc-arc-apelim",
749 "ObjC ARC autorelease pool elimination",
750 false, false)
751
752 Pass *llvm::createObjCARCAPElimPass() {
753 return new ObjCARCAPElim();
754 }
755
756 void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const {
757 AU.setPreservesCFG();
758 }
759
760 /// Interprocedurally determine if calls made by the given call site can
761 /// possibly produce autoreleases.
762 bool ObjCARCAPElim::MayAutorelease(ImmutableCallSite CS, unsigned Depth) {
763 if (const Function *Callee = CS.getCalledFunction()) {
764 if (Callee->isDeclaration() || Callee->mayBeOverridden())
765 return true;
766 for (Function::const_iterator I = Callee->begin(), E = Callee->end();
767 I != E; ++I) {
768 const BasicBlock *BB = I;
769 for (BasicBlock::const_iterator J = BB->begin(), F = BB->end();
770 J != F; ++J)
771 if (ImmutableCallSite JCS = ImmutableCallSite(J))
772 // This recursion depth limit is arbitrary. It's just great
773 // enough to cover known interesting testcases.
774 if (Depth < 3 &&
775 !JCS.onlyReadsMemory() &&
776 MayAutorelease(JCS, Depth + 1))
777 return true;
778 }
779 return false;
780 }
781
782 return true;
783 }
784
785 bool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) {
786 bool Changed = false;
787
788 Instruction *Push = 0;
789 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
790 Instruction *Inst = I++;
791 switch (GetBasicInstructionClass(Inst)) {
792 case IC_AutoreleasepoolPush:
793 Push = Inst;
794 break;
795 case IC_AutoreleasepoolPop:
796 // If this pop matches a push and nothing in between can autorelease,
797 // zap the pair.
798 if (Push && cast(Inst)->getArgOperand(0) == Push) {
799 Changed = true;
800 DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop "
801 "autorelease pair:\n"
802 " Pop: " << *Inst << "\n"
803 << " Push: " << *Push << "\n");
804 Inst->eraseFromParent();
805 Push->eraseFromParent();
806 }
807 Push = 0;
808 break;
809 case IC_CallOrUser:
810 if (MayAutorelease(ImmutableCallSite(Inst)))
811 Push = 0;
812 break;
813 default:
814 break;
815 }
816 }
817
818 return Changed;
819 }
820
821 bool ObjCARCAPElim::runOnModule(Module &M) {
822 if (!EnableARCOpts)
823 return false;
824
825 // If nothing in the Module uses ARC, don't do anything.
826 if (!ModuleHasARC(M))
827 return false;
828
829 // Find the llvm.global_ctors variable, as the first step in
830 // identifying the global constructors. In theory, unnecessary autorelease
831 // pools could occur anywhere, but in practice it's pretty rare. Global
832 // ctors are a place where autorelease pools get inserted automatically,
833 // so it's pretty common for them to be unnecessary, and it's pretty
834 // profitable to eliminate them.
835 GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
836 if (!GV)
837 return false;
838
839 assert(GV->hasDefinitiveInitializer() &&
840 "llvm.global_ctors is uncooperative!");
841
842 bool Changed = false;
843
844 // Dig the constructor functions out of GV's initializer.
845 ConstantArray *Init = cast(GV->getInitializer());
846 for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end();
847 OI != OE; ++OI) {
848 Value *Op = *OI;
849 // llvm.global_ctors is an array of pairs where the second members
850 // are constructor functions.
851 Function *F = dyn_cast(cast(Op)->getOperand(1));
852 // If the user used a constructor function with the wrong signature and
853 // it got bitcasted or whatever, look the other way.
854 if (!F)
855 continue;
856 // Only look at function definitions.
857 if (F->isDeclaration())
858 continue;
859 // Only look at functions with one basic block.
860 if (llvm::next(F->begin()) != F->end())
861 continue;
862 // Ok, a single-block constructor function definition. Try to optimize it.
863 Changed |= OptimizeBB(F->begin());
864 }
865
866 return Changed;
867722 }
868723
869724 /// @}