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:
parent
85f907b9af
commit
1a477f367f
@ -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&);
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user