Skip to content

Commit 024979b

Browse files
committed
[ObjCARC][NewPM] Port objc-arc-contract to NPM
Similar to https://reviews.llvm.org/D86178. This is a module pass instead of a function pass since ARCRuntimeEntryPoints can lazily add function declarations. Reviewed By: ahatanak Differential Revision: https://reviews.llvm.org/D87806
1 parent 742250b commit 024979b

File tree

6 files changed

+122
-79
lines changed

6 files changed

+122
-79
lines changed

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ void initializeNaryReassociateLegacyPassPass(PassRegistry&);
317317
void initializeNewGVNLegacyPassPass(PassRegistry&);
318318
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
319319
void initializeObjCARCAPElimPass(PassRegistry&);
320-
void initializeObjCARCContractPass(PassRegistry&);
320+
void initializeObjCARCContractLegacyPassPass(PassRegistry &);
321321
void initializeObjCARCExpandPass(PassRegistry&);
322322
void initializeObjCARCOptLegacyPassPass(PassRegistry &);
323323
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&);

llvm/include/llvm/Transforms/ObjCARC.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ Pass *createObjCARCContractPass();
4444
//
4545
Pass *createObjCARCOptPass();
4646

47-
class ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
48-
public:
49-
ObjCARCOptPass() {}
47+
struct ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
48+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
49+
};
5050

51+
struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
5152
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
5253
};
5354

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ MODULE_PASS("mergefunc", MergeFunctionsPass())
7070
MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
7171
MODULE_PASS("no-op-module", NoOpModulePass())
7272
MODULE_PASS("objc-arc", ObjCARCOptPass())
73+
MODULE_PASS("objc-arc-contract", ObjCARCContractPass())
7374
MODULE_PASS("partial-inliner", PartialInlinerPass())
7475
MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
7576
MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())

llvm/lib/Transforms/ObjCARC/ObjCARC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
2929
initializeObjCARCAAWrapperPassPass(Registry);
3030
initializeObjCARCAPElimPass(Registry);
3131
initializeObjCARCExpandPass(Registry);
32-
initializeObjCARCContractPass(Registry);
32+
initializeObjCARCContractLegacyPassPass(Registry);
3333
initializeObjCARCOptLegacyPassPass(Registry);
3434
initializePAEvalPass(Registry);
3535
}

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 114 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
#include "llvm/IR/InlineAsm.h"
3636
#include "llvm/IR/InstIterator.h"
3737
#include "llvm/IR/Operator.h"
38+
#include "llvm/IR/PassManager.h"
3839
#include "llvm/InitializePasses.h"
3940
#include "llvm/Support/CommandLine.h"
4041
#include "llvm/Support/Debug.h"
4142
#include "llvm/Support/raw_ostream.h"
43+
#include "llvm/Transforms/ObjCARC.h"
4244

4345
using namespace llvm;
4446
using namespace llvm::objcarc;
@@ -53,59 +55,66 @@ STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
5355
//===----------------------------------------------------------------------===//
5456

5557
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+
};
109118
}
110119

111120
//===----------------------------------------------------------------------===//
@@ -542,19 +551,32 @@ bool ObjCARCContract::tryToPeepholeInstruction(
542551
// Top Level Driver
543552
//===----------------------------------------------------------------------===//
544553

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) {
546570
if (!EnableARCOpts)
547571
return false;
548572

549573
// If nothing in the Module uses ARC, don't do anything.
550574
if (!Run)
551575
return false;
552576

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);
558580

559581
DenseMap<BasicBlock *, ColorVector> BlockColors;
560582
if (F.hasPersonalityFn() &&
@@ -720,33 +742,51 @@ bool ObjCARCContract::runOnFunction(Function &F) {
720742
// Misc Pass Manager
721743
//===----------------------------------------------------------------------===//
722744

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",
725747
"ObjC ARC contraction", false, false)
726748
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
727749
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
728-
INITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract",
750+
INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
729751
"ObjC ARC contraction", false, false)
730752

731-
void ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const {
753+
void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
732754
AU.addRequired<AAResultsWrapperPass>();
733755
AU.addRequired<DominatorTreeWrapperPass>();
734756
AU.setPreservesCFG();
735757
}
736758

737-
Pass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); }
759+
Pass *llvm::createObjCARCContractPass() {
760+
return new ObjCARCContractLegacyPass();
761+
}
738762

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+
}
744766

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+
}
746772

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);
750777

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();
752792
}

llvm/test/Transforms/ObjCARC/contract.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
2+
; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s
23

34
target datalayout = "e-p:64:64:64"
45

0 commit comments

Comments
 (0)