35
35
#include " llvm/IR/InlineAsm.h"
36
36
#include " llvm/IR/InstIterator.h"
37
37
#include " llvm/IR/Operator.h"
38
+ #include " llvm/IR/PassManager.h"
38
39
#include " llvm/InitializePasses.h"
39
40
#include " llvm/Support/CommandLine.h"
40
41
#include " llvm/Support/Debug.h"
41
42
#include " llvm/Support/raw_ostream.h"
43
+ #include " llvm/Transforms/ObjCARC.h"
42
44
43
45
using namespace llvm ;
44
46
using namespace llvm ::objcarc;
@@ -53,59 +55,66 @@ STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
53
55
// ===----------------------------------------------------------------------===//
54
56
55
57
namespace {
56
- // / Late ARC optimizations
57
- // /
58
- // / These change the IR in a way that makes it difficult to be analyzed by
59
- // / ObjCARCOpt, so it's run late.
60
- class ObjCARCContract : public FunctionPass {
61
- bool Changed;
62
- AliasAnalysis *AA;
63
- DominatorTree *DT;
64
- ProvenanceAnalysis PA;
65
- ARCRuntimeEntryPoints EP;
66
-
67
- // / A flag indicating whether this optimization pass should run.
68
- bool Run;
69
-
70
- // / The inline asm string to insert between calls and RetainRV calls to make
71
- // / the optimization work on targets which need it.
72
- const MDString *RVInstMarker;
73
-
74
- // / The set of inserted objc_storeStrong calls. If at the end of walking the
75
- // / function we have found no alloca instructions, these calls can be marked
76
- // / "tail".
77
- SmallPtrSet<CallInst *, 8 > StoreStrongCalls;
78
-
79
- // / Returns true if we eliminated Inst.
80
- bool tryToPeepholeInstruction (
81
- Function &F, Instruction *Inst, inst_iterator &Iter,
82
- SmallPtrSetImpl<Instruction *> &DepInsts,
83
- SmallPtrSetImpl<const BasicBlock *> &Visited,
84
- bool &TailOkForStoreStrong,
85
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
86
-
87
- bool optimizeRetainCall (Function &F, Instruction *Retain);
88
-
89
- bool
90
- contractAutorelease (Function &F, Instruction *Autorelease,
91
- ARCInstKind Class,
92
- SmallPtrSetImpl<Instruction *> &DependingInstructions,
93
- SmallPtrSetImpl<const BasicBlock *> &Visited);
94
-
95
- void tryToContractReleaseIntoStoreStrong (
96
- Instruction *Release, inst_iterator &Iter,
97
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
98
-
99
- void getAnalysisUsage (AnalysisUsage &AU) const override ;
100
- bool doInitialization (Module &M) override ;
101
- bool runOnFunction (Function &F) override ;
102
-
103
- public:
104
- static char ID;
105
- ObjCARCContract () : FunctionPass(ID) {
106
- initializeObjCARCContractPass (*PassRegistry::getPassRegistry ());
107
- }
108
- };
58
+ // / Late ARC optimizations
59
+ // /
60
+ // / These change the IR in a way that makes it difficult to be analyzed by
61
+ // / ObjCARCOpt, so it's run late.
62
+
63
+ class ObjCARCContract {
64
+ bool Changed;
65
+ AliasAnalysis *AA;
66
+ DominatorTree *DT;
67
+ ProvenanceAnalysis PA;
68
+ ARCRuntimeEntryPoints EP;
69
+
70
+ // / A flag indicating whether this optimization pass should run.
71
+ bool Run;
72
+
73
+ // / The inline asm string to insert between calls and RetainRV calls to make
74
+ // / the optimization work on targets which need it.
75
+ const MDString *RVInstMarker;
76
+
77
+ // / The set of inserted objc_storeStrong calls. If at the end of walking the
78
+ // / function we have found no alloca instructions, these calls can be marked
79
+ // / "tail".
80
+ SmallPtrSet<CallInst *, 8 > StoreStrongCalls;
81
+
82
+ // / Returns true if we eliminated Inst.
83
+ bool tryToPeepholeInstruction (
84
+ Function &F, Instruction *Inst, inst_iterator &Iter,
85
+ SmallPtrSetImpl<Instruction *> &DepInsts,
86
+ SmallPtrSetImpl<const BasicBlock *> &Visited, bool &TailOkForStoreStrong,
87
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors);
88
+
89
+ bool optimizeRetainCall (Function &F, Instruction *Retain);
90
+
91
+ bool
92
+ contractAutorelease (Function &F, Instruction *Autorelease, ARCInstKind Class,
93
+ SmallPtrSetImpl<Instruction *> &DependingInstructions,
94
+ SmallPtrSetImpl<const BasicBlock *> &Visited);
95
+
96
+ void tryToContractReleaseIntoStoreStrong (
97
+ Instruction *Release, inst_iterator &Iter,
98
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors);
99
+
100
+ public:
101
+ bool init (Module &M);
102
+ bool run (Function &F, AAResults *AA, DominatorTree *DT);
103
+ };
104
+
105
+ class ObjCARCContractLegacyPass : public FunctionPass {
106
+ ObjCARCContract OCARCC;
107
+
108
+ public:
109
+ void getAnalysisUsage (AnalysisUsage &AU) const override ;
110
+ bool doInitialization (Module &M) override ;
111
+ bool runOnFunction (Function &F) override ;
112
+
113
+ static char ID;
114
+ ObjCARCContractLegacyPass () : FunctionPass(ID) {
115
+ initializeObjCARCContractLegacyPassPass (*PassRegistry::getPassRegistry ());
116
+ }
117
+ };
109
118
}
110
119
111
120
// ===----------------------------------------------------------------------===//
@@ -542,19 +551,32 @@ bool ObjCARCContract::tryToPeepholeInstruction(
542
551
// Top Level Driver
543
552
// ===----------------------------------------------------------------------===//
544
553
545
- bool ObjCARCContract::runOnFunction (Function &F) {
554
+ bool ObjCARCContract::init (Module &M) {
555
+ // If nothing in the Module uses ARC, don't do anything.
556
+ Run = ModuleHasARC (M);
557
+ if (!Run)
558
+ return false ;
559
+
560
+ EP.init (&M);
561
+
562
+ // Initialize RVInstMarker.
563
+ const char *MarkerKey = " clang.arc.retainAutoreleasedReturnValueMarker" ;
564
+ RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag (MarkerKey));
565
+
566
+ return false ;
567
+ }
568
+
569
+ bool ObjCARCContract::run (Function &F, AAResults *A, DominatorTree *D) {
546
570
if (!EnableARCOpts)
547
571
return false ;
548
572
549
573
// If nothing in the Module uses ARC, don't do anything.
550
574
if (!Run)
551
575
return false ;
552
576
553
- Changed = false ;
554
- AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
555
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
556
-
557
- PA.setAA (&getAnalysis<AAResultsWrapperPass>().getAAResults ());
577
+ AA = A;
578
+ DT = D;
579
+ PA.setAA (A);
558
580
559
581
DenseMap<BasicBlock *, ColorVector> BlockColors;
560
582
if (F.hasPersonalityFn () &&
@@ -720,33 +742,51 @@ bool ObjCARCContract::runOnFunction(Function &F) {
720
742
// Misc Pass Manager
721
743
// ===----------------------------------------------------------------------===//
722
744
723
- char ObjCARCContract ::ID = 0 ;
724
- INITIALIZE_PASS_BEGIN (ObjCARCContract , " objc-arc-contract" ,
745
+ char ObjCARCContractLegacyPass ::ID = 0 ;
746
+ INITIALIZE_PASS_BEGIN (ObjCARCContractLegacyPass , " objc-arc-contract" ,
725
747
" ObjC ARC contraction" , false , false )
726
748
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
727
749
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
728
- INITIALIZE_PASS_END(ObjCARCContract , " objc-arc-contract" ,
750
+ INITIALIZE_PASS_END(ObjCARCContractLegacyPass , " objc-arc-contract" ,
729
751
" ObjC ARC contraction" , false , false )
730
752
731
- void ObjCARCContract ::getAnalysisUsage(AnalysisUsage &AU) const {
753
+ void ObjCARCContractLegacyPass ::getAnalysisUsage(AnalysisUsage &AU) const {
732
754
AU.addRequired <AAResultsWrapperPass>();
733
755
AU.addRequired <DominatorTreeWrapperPass>();
734
756
AU.setPreservesCFG ();
735
757
}
736
758
737
- Pass *llvm::createObjCARCContractPass () { return new ObjCARCContract (); }
759
+ Pass *llvm::createObjCARCContractPass () {
760
+ return new ObjCARCContractLegacyPass ();
761
+ }
738
762
739
- bool ObjCARCContract::doInitialization (Module &M) {
740
- // If nothing in the Module uses ARC, don't do anything.
741
- Run = ModuleHasARC (M);
742
- if (!Run)
743
- return false ;
763
+ bool ObjCARCContractLegacyPass::doInitialization (Module &M) {
764
+ return OCARCC.init (M);
765
+ }
744
766
745
- EP.init (&M);
767
+ bool ObjCARCContractLegacyPass::runOnFunction (Function &F) {
768
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
769
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
770
+ return OCARCC.run (F, AA, DT);
771
+ }
746
772
747
- // Initialize RVInstMarker.
748
- const char *MarkerKey = " clang.arc.retainAutoreleasedReturnValueMarker" ;
749
- RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag (MarkerKey));
773
+ PreservedAnalyses ObjCARCContractPass::run (Module &M,
774
+ ModuleAnalysisManager &AM) {
775
+ ObjCARCContract OCAC;
776
+ OCAC.init (M);
750
777
751
- return false ;
778
+ auto &FAM = AM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
779
+ bool Changed = false ;
780
+ for (Function &F : M) {
781
+ if (F.isDeclaration ())
782
+ continue ;
783
+ Changed |= OCAC.run (F, &FAM.getResult <AAManager>(F),
784
+ &FAM.getResult <DominatorTreeAnalysis>(F));
785
+ }
786
+ if (Changed) {
787
+ PreservedAnalyses PA;
788
+ PA.preserveSet <CFGAnalyses>();
789
+ return PA;
790
+ }
791
+ return PreservedAnalyses::all ();
752
792
}
0 commit comments