1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[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
This commit is contained in:
Arthur Eubanks 2020-09-02 16:22:24 -07:00
parent 85f907b9af
commit 1a477f367f
6 changed files with 117 additions and 74 deletions

View File

@ -317,7 +317,7 @@ void initializeNaryReassociateLegacyPassPass(PassRegistry&);
void initializeNewGVNLegacyPassPass(PassRegistry&); void initializeNewGVNLegacyPassPass(PassRegistry&);
void initializeObjCARCAAWrapperPassPass(PassRegistry&); void initializeObjCARCAAWrapperPassPass(PassRegistry&);
void initializeObjCARCAPElimPass(PassRegistry&); void initializeObjCARCAPElimPass(PassRegistry&);
void initializeObjCARCContractPass(PassRegistry&); void initializeObjCARCContractLegacyPassPass(PassRegistry &);
void initializeObjCARCExpandPass(PassRegistry&); void initializeObjCARCExpandPass(PassRegistry&);
void initializeObjCARCOptLegacyPassPass(PassRegistry &); void initializeObjCARCOptLegacyPassPass(PassRegistry &);
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&); void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&);

View File

@ -44,10 +44,11 @@ Pass *createObjCARCContractPass();
// //
Pass *createObjCARCOptPass(); Pass *createObjCARCOptPass();
class ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> { struct ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
public: PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
ObjCARCOptPass() {} };
struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
}; };

View File

@ -70,6 +70,7 @@ MODULE_PASS("mergefunc", MergeFunctionsPass())
MODULE_PASS("name-anon-globals", NameAnonGlobalPass()) MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("no-op-module", NoOpModulePass())
MODULE_PASS("objc-arc", ObjCARCOptPass()) MODULE_PASS("objc-arc", ObjCARCOptPass())
MODULE_PASS("objc-arc-contract", ObjCARCContractPass())
MODULE_PASS("partial-inliner", PartialInlinerPass()) MODULE_PASS("partial-inliner", PartialInlinerPass())
MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion()) MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen()) MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())

View File

@ -29,7 +29,7 @@ void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
initializeObjCARCAAWrapperPassPass(Registry); initializeObjCARCAAWrapperPassPass(Registry);
initializeObjCARCAPElimPass(Registry); initializeObjCARCAPElimPass(Registry);
initializeObjCARCExpandPass(Registry); initializeObjCARCExpandPass(Registry);
initializeObjCARCContractPass(Registry); initializeObjCARCContractLegacyPassPass(Registry);
initializeObjCARCOptLegacyPassPass(Registry); initializeObjCARCOptLegacyPassPass(Registry);
initializePAEvalPass(Registry); initializePAEvalPass(Registry);
} }

View File

@ -35,10 +35,12 @@
#include "llvm/IR/InlineAsm.h" #include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h" #include "llvm/IR/InstIterator.h"
#include "llvm/IR/Operator.h" #include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h" #include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/ObjCARC.h"
using namespace llvm; using namespace llvm;
using namespace llvm::objcarc; using namespace llvm::objcarc;
@ -53,59 +55,66 @@ STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace { namespace {
/// Late ARC optimizations /// Late ARC optimizations
/// ///
/// These change the IR in a way that makes it difficult to be analyzed by /// These change the IR in a way that makes it difficult to be analyzed by
/// ObjCARCOpt, so it's run late. /// ObjCARCOpt, so it's run late.
class ObjCARCContract : public FunctionPass {
bool Changed;
AliasAnalysis *AA;
DominatorTree *DT;
ProvenanceAnalysis PA;
ARCRuntimeEntryPoints EP;
/// A flag indicating whether this optimization pass should run. class ObjCARCContract {
bool Run; bool Changed;
AliasAnalysis *AA;
DominatorTree *DT;
ProvenanceAnalysis PA;
ARCRuntimeEntryPoints EP;
/// The inline asm string to insert between calls and RetainRV calls to make /// A flag indicating whether this optimization pass should run.
/// the optimization work on targets which need it. bool Run;
const MDString *RVInstMarker;
/// The set of inserted objc_storeStrong calls. If at the end of walking the /// The inline asm string to insert between calls and RetainRV calls to make
/// function we have found no alloca instructions, these calls can be marked /// the optimization work on targets which need it.
/// "tail". const MDString *RVInstMarker;
SmallPtrSet<CallInst *, 8> StoreStrongCalls;
/// Returns true if we eliminated Inst. /// The set of inserted objc_storeStrong calls. If at the end of walking the
bool tryToPeepholeInstruction( /// function we have found no alloca instructions, these calls can be marked
Function &F, Instruction *Inst, inst_iterator &Iter, /// "tail".
SmallPtrSetImpl<Instruction *> &DepInsts, SmallPtrSet<CallInst *, 8> StoreStrongCalls;
SmallPtrSetImpl<const BasicBlock *> &Visited,
bool &TailOkForStoreStrong,
const DenseMap<BasicBlock *, ColorVector> &BlockColors);
bool optimizeRetainCall(Function &F, Instruction *Retain); /// Returns true if we eliminated Inst.
bool tryToPeepholeInstruction(
Function &F, Instruction *Inst, inst_iterator &Iter,
SmallPtrSetImpl<Instruction *> &DepInsts,
SmallPtrSetImpl<const BasicBlock *> &Visited, bool &TailOkForStoreStrong,
const DenseMap<BasicBlock *, ColorVector> &BlockColors);
bool bool optimizeRetainCall(Function &F, Instruction *Retain);
contractAutorelease(Function &F, Instruction *Autorelease,
ARCInstKind Class,
SmallPtrSetImpl<Instruction *> &DependingInstructions,
SmallPtrSetImpl<const BasicBlock *> &Visited);
void tryToContractReleaseIntoStoreStrong( bool
Instruction *Release, inst_iterator &Iter, contractAutorelease(Function &F, Instruction *Autorelease, ARCInstKind Class,
const DenseMap<BasicBlock *, ColorVector> &BlockColors); SmallPtrSetImpl<Instruction *> &DependingInstructions,
SmallPtrSetImpl<const BasicBlock *> &Visited);
void getAnalysisUsage(AnalysisUsage &AU) const override; void tryToContractReleaseIntoStoreStrong(
bool doInitialization(Module &M) override; Instruction *Release, inst_iterator &Iter,
bool runOnFunction(Function &F) override; const DenseMap<BasicBlock *, ColorVector> &BlockColors);
public: public:
static char ID; bool init(Module &M);
ObjCARCContract() : FunctionPass(ID) { bool run(Function &F, AAResults *AA, DominatorTree *DT);
initializeObjCARCContractPass(*PassRegistry::getPassRegistry()); };
}
}; class ObjCARCContractLegacyPass : public FunctionPass {
ObjCARCContract OCARCC;
public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool doInitialization(Module &M) override;
bool runOnFunction(Function &F) override;
static char ID;
ObjCARCContractLegacyPass() : FunctionPass(ID) {
initializeObjCARCContractLegacyPassPass(*PassRegistry::getPassRegistry());
}
};
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -542,7 +551,22 @@ bool ObjCARCContract::tryToPeepholeInstruction(
// Top Level Driver // Top Level Driver
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool ObjCARCContract::runOnFunction(Function &F) { bool ObjCARCContract::init(Module &M) {
// If nothing in the Module uses ARC, don't do anything.
Run = ModuleHasARC(M);
if (!Run)
return false;
EP.init(&M);
// Initialize RVInstMarker.
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
return false;
}
bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
if (!EnableARCOpts) if (!EnableARCOpts)
return false; return false;
@ -550,11 +574,9 @@ bool ObjCARCContract::runOnFunction(Function &F) {
if (!Run) if (!Run)
return false; return false;
Changed = false; AA = A;
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); DT = D;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); PA.setAA(A);
PA.setAA(&getAnalysis<AAResultsWrapperPass>().getAAResults());
DenseMap<BasicBlock *, ColorVector> BlockColors; DenseMap<BasicBlock *, ColorVector> BlockColors;
if (F.hasPersonalityFn() && if (F.hasPersonalityFn() &&
@ -720,33 +742,51 @@ bool ObjCARCContract::runOnFunction(Function &F) {
// Misc Pass Manager // Misc Pass Manager
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
char ObjCARCContract::ID = 0; char ObjCARCContractLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(ObjCARCContract, "objc-arc-contract", INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
"ObjC ARC contraction", false, false) "ObjC ARC contraction", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract", INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
"ObjC ARC contraction", false, false) "ObjC ARC contraction", false, false)
void ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const { void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>(); AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>(); AU.addRequired<DominatorTreeWrapperPass>();
AU.setPreservesCFG(); AU.setPreservesCFG();
} }
Pass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); } Pass *llvm::createObjCARCContractPass() {
return new ObjCARCContractLegacyPass();
bool ObjCARCContract::doInitialization(Module &M) { }
// If nothing in the Module uses ARC, don't do anything.
Run = ModuleHasARC(M); bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
if (!Run) return OCARCC.init(M);
return false; }
EP.init(&M); bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
// Initialize RVInstMarker. auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; return OCARCC.run(F, AA, DT);
RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey)); }
return false; PreservedAnalyses ObjCARCContractPass::run(Module &M,
ModuleAnalysisManager &AM) {
ObjCARCContract OCAC;
OCAC.init(M);
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
bool Changed = false;
for (Function &F : M) {
if (F.isDeclaration())
continue;
Changed |= OCAC.run(F, &FAM.getResult<AAManager>(F),
&FAM.getResult<DominatorTreeAnalysis>(F));
}
if (Changed) {
PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
return PA;
}
return PreservedAnalyses::all();
} }

View File

@ -1,4 +1,5 @@
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s ; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s
target datalayout = "e-p:64:64:64" target datalayout = "e-p:64:64:64"