mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Update Swift's LLVM passes to include new pass manager versions
This commit is contained in:
@@ -31,6 +31,11 @@ namespace swift {
|
||||
bool invalidate(llvm::Function &,
|
||||
const llvm::PreservedAnalyses &) { return false; }
|
||||
|
||||
bool invalidate(llvm::Function &, const llvm::PreservedAnalyses &,
|
||||
llvm::FunctionAnalysisManager::Invalidator &) {
|
||||
return false;
|
||||
}
|
||||
|
||||
using AAResultBase::getModRefInfo;
|
||||
llvm::ModRefInfo getModRefInfo(const llvm::CallBase *Call,
|
||||
const llvm::MemoryLocation &Loc) {
|
||||
@@ -57,27 +62,34 @@ namespace swift {
|
||||
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
|
||||
};
|
||||
|
||||
class SwiftRCIdentity : public llvm::ImmutablePass {
|
||||
class SwiftAA : public llvm::AnalysisInfoMixin<SwiftAA> {
|
||||
friend llvm::AnalysisInfoMixin<SwiftAA>;
|
||||
|
||||
static llvm::AnalysisKey Key;
|
||||
|
||||
public:
|
||||
static char ID; // Class identification, replacement for typeinfo
|
||||
SwiftRCIdentity() : ImmutablePass(ID) {}
|
||||
using Result = SwiftAAResult;
|
||||
|
||||
SwiftAAResult run(llvm::Function &F, llvm::FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
class SwiftRCIdentity {
|
||||
public:
|
||||
SwiftRCIdentity() {}
|
||||
|
||||
/// Returns the root of the RC-equivalent value for the given V.
|
||||
llvm::Value *getSwiftRCIdentityRoot(llvm::Value *V);
|
||||
|
||||
private:
|
||||
enum { MaxRecursionDepth = 16 };
|
||||
bool doInitialization(llvm::Module &M) override;
|
||||
|
||||
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
llvm::Value *stripPointerCasts(llvm::Value *Val);
|
||||
llvm::Value *stripReferenceForwarding(llvm::Value *Val);
|
||||
};
|
||||
|
||||
class SwiftARCOpt : public llvm::FunctionPass {
|
||||
/// Swift RC Identity analysis.
|
||||
SwiftRCIdentity *RC;
|
||||
SwiftRCIdentity RC;
|
||||
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
|
||||
virtual bool runOnFunction(llvm::Function &F) override;
|
||||
public:
|
||||
@@ -85,9 +97,16 @@ namespace swift {
|
||||
SwiftARCOpt();
|
||||
};
|
||||
|
||||
struct SwiftARCOptPass : public llvm::PassInfoMixin<SwiftARCOptPass> {
|
||||
SwiftRCIdentity RC;
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
class SwiftARCContract : public llvm::FunctionPass {
|
||||
/// Swift RC Identity analysis.
|
||||
SwiftRCIdentity *RC;
|
||||
SwiftRCIdentity RC;
|
||||
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
|
||||
virtual bool runOnFunction(llvm::Function &F) override;
|
||||
public:
|
||||
@@ -95,6 +114,14 @@ namespace swift {
|
||||
SwiftARCContract() : llvm::FunctionPass(ID) {}
|
||||
};
|
||||
|
||||
struct SwiftARCContractPass
|
||||
: public llvm::PassInfoMixin<SwiftARCContractPass> {
|
||||
SwiftRCIdentity RC;
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
class InlineTreePrinter : public llvm::ModulePass {
|
||||
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
|
||||
virtual bool runOnModule(llvm::Module &M) override;
|
||||
@@ -102,6 +129,30 @@ namespace swift {
|
||||
static char ID;
|
||||
InlineTreePrinter() : llvm::ModulePass(ID) {}
|
||||
};
|
||||
|
||||
class SwiftMergeFunctionsPass
|
||||
: public llvm::PassInfoMixin<SwiftMergeFunctionsPass> {
|
||||
bool ptrAuthEnabled = false;
|
||||
unsigned ptrAuthKey = 0;
|
||||
|
||||
public:
|
||||
SwiftMergeFunctionsPass(bool ptrAuthEnabled, unsigned ptrAuthKey)
|
||||
: ptrAuthEnabled(ptrAuthEnabled), ptrAuthKey(ptrAuthKey) {}
|
||||
llvm::PreservedAnalyses run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct SwiftDbgAddrBlockSplitterPass
|
||||
: public llvm::PassInfoMixin<SwiftDbgAddrBlockSplitterPass> {
|
||||
llvm::PreservedAnalyses run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct InlineTreePrinterPass
|
||||
: public llvm::PassInfoMixin<InlineTreePrinterPass> {
|
||||
llvm::PreservedAnalyses run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM);
|
||||
};
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,11 +20,10 @@ namespace llvm {
|
||||
class PassRegistry;
|
||||
|
||||
void initializeSwiftAAWrapperPassPass(PassRegistry &);
|
||||
void initializeSwiftRCIdentityPass(PassRegistry &);
|
||||
void initializeSwiftARCOptPass(PassRegistry &);
|
||||
void initializeSwiftARCContractPass(PassRegistry &);
|
||||
void initializeInlineTreePrinterPass(PassRegistry &);
|
||||
void initializeSwiftMergeFunctionsPass(PassRegistry &);
|
||||
void initializeLegacySwiftMergeFunctionsPass(PassRegistry &);
|
||||
void initializeSwiftDbgAddrBlockSplitterPass(PassRegistry &);
|
||||
}
|
||||
|
||||
@@ -32,11 +31,10 @@ namespace swift {
|
||||
llvm::FunctionPass *createSwiftARCOptPass();
|
||||
llvm::FunctionPass *createSwiftARCContractPass();
|
||||
llvm::ModulePass *createInlineTreePrinterPass();
|
||||
llvm::ModulePass *createSwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
||||
unsigned ptrAuthKey);
|
||||
llvm::ModulePass *createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
||||
unsigned ptrAuthKey);
|
||||
llvm::FunctionPass *createSwiftDbgAddrBlockSplitter();
|
||||
llvm::ImmutablePass *createSwiftAAWrapperPass();
|
||||
llvm::ImmutablePass *createSwiftRCIdentityPass();
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
@@ -290,7 +290,7 @@ performOptimizationsUsingLegacyPassManger(const IRGenOptions &Opts,
|
||||
if (Builder.OptLevel > 0) {
|
||||
const PointerAuthSchema &schema = Opts.PointerAuth.FunctionPointers;
|
||||
unsigned key = (schema.isEnabled() ? schema.getKey() : 0);
|
||||
PM.add(createSwiftMergeFunctionsPass(schema.isEnabled(), key));
|
||||
PM.add(createLegacySwiftMergeFunctionsPass(schema.isEnabled(), key));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ struct SwiftDbgAddrBlockSplitter : FunctionPass {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
|
||||
static bool split(Function &fn) {
|
||||
SmallVector<Instruction *, 32> breakBlockPoints;
|
||||
|
||||
// If we are in the first block,
|
||||
@@ -65,6 +65,10 @@ bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
|
||||
return madeChange;
|
||||
}
|
||||
|
||||
bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
|
||||
return split(fn);
|
||||
}
|
||||
|
||||
char SwiftDbgAddrBlockSplitter::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(SwiftDbgAddrBlockSplitter,
|
||||
"swift-dbg-addr-block-splitter",
|
||||
@@ -79,3 +83,12 @@ llvm::FunctionPass *swift::createSwiftDbgAddrBlockSplitter() {
|
||||
*llvm::PassRegistry::getPassRegistry());
|
||||
return new SwiftDbgAddrBlockSplitter();
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses
|
||||
swift::SwiftDbgAddrBlockSplitterPass::run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM) {
|
||||
bool changed = split(F);
|
||||
if (!changed)
|
||||
return PreservedAnalyses::all();
|
||||
return PreservedAnalyses::none();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class SwiftARCContractImpl {
|
||||
bool Changed;
|
||||
|
||||
/// Swift RC Identity.
|
||||
SwiftRCIdentity *RC;
|
||||
SwiftRCIdentity RC;
|
||||
|
||||
/// The function that we are processing.
|
||||
Function &F;
|
||||
@@ -72,8 +72,7 @@ class SwiftARCContractImpl {
|
||||
/// The entry point builder that is used to construct ARC entry points.
|
||||
ARCEntryPointBuilder B;
|
||||
public:
|
||||
SwiftARCContractImpl(Function &InF, SwiftRCIdentity *InRC)
|
||||
: Changed(false), RC(InRC), F(InF), B(F) {}
|
||||
SwiftARCContractImpl(Function &InF) : Changed(false), F(InF), B(F) {}
|
||||
|
||||
// The top level run routine of the pass.
|
||||
bool run();
|
||||
@@ -109,7 +108,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
B.createRetainN(RC->getSwiftRCIdentityRoot(O), RetainList.size(), RI);
|
||||
B.createRetainN(RC.getSwiftRCIdentityRoot(O), RetainList.size(), RI);
|
||||
|
||||
// Replace all uses of the retain instructions with our new retainN and
|
||||
// then delete them.
|
||||
@@ -135,7 +134,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
B.createReleaseN(RC->getSwiftRCIdentityRoot(O), ReleaseList.size(), RI);
|
||||
B.createReleaseN(RC.getSwiftRCIdentityRoot(O), ReleaseList.size(), RI);
|
||||
|
||||
// Remove all old release instructions.
|
||||
for (auto *Inst : ReleaseList) {
|
||||
@@ -159,7 +158,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
B.createUnknownObjectRetainN(RC->getSwiftRCIdentityRoot(O),
|
||||
B.createUnknownObjectRetainN(RC.getSwiftRCIdentityRoot(O),
|
||||
UnknownObjectRetainList.size(), RI);
|
||||
|
||||
// Replace all uses of the retain instructions with our new retainN and
|
||||
@@ -187,7 +186,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
B.createUnknownObjectReleaseN(RC->getSwiftRCIdentityRoot(O),
|
||||
B.createUnknownObjectReleaseN(RC.getSwiftRCIdentityRoot(O),
|
||||
UnknownObjectReleaseList.size(), RI);
|
||||
|
||||
// Remove all old release instructions.
|
||||
@@ -214,7 +213,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
}
|
||||
}
|
||||
// Bridge retain may modify the input reference before forwarding it.
|
||||
auto *I = B.createBridgeRetainN(RC->getSwiftRCIdentityRoot(O),
|
||||
auto *I = B.createBridgeRetainN(RC.getSwiftRCIdentityRoot(O),
|
||||
BridgeRetainList.size(), RI);
|
||||
|
||||
// Remove all old retain instructions.
|
||||
@@ -246,8 +245,8 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
B.createBridgeReleaseN(RC->getSwiftRCIdentityRoot(O),
|
||||
BridgeReleaseList.size(), RI);
|
||||
B.createBridgeReleaseN(RC.getSwiftRCIdentityRoot(O),
|
||||
BridgeReleaseList.size(), RI);
|
||||
|
||||
// Remove all old release instructions.
|
||||
for (auto *Inst : BridgeReleaseList) {
|
||||
@@ -290,7 +289,7 @@ bool SwiftARCContractImpl::run() {
|
||||
continue;
|
||||
case RT_Retain: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.RetainList.push_back(CI);
|
||||
@@ -298,7 +297,7 @@ bool SwiftARCContractImpl::run() {
|
||||
}
|
||||
case RT_UnknownObjectRetain: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.UnknownObjectRetainList.push_back(CI);
|
||||
@@ -307,7 +306,7 @@ bool SwiftARCContractImpl::run() {
|
||||
case RT_Release: {
|
||||
// Stash any releases that we see.
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.ReleaseList.push_back(CI);
|
||||
@@ -316,7 +315,7 @@ bool SwiftARCContractImpl::run() {
|
||||
case RT_UnknownObjectRelease: {
|
||||
// Stash any releases that we see.
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.UnknownObjectReleaseList.push_back(CI);
|
||||
@@ -324,7 +323,7 @@ bool SwiftARCContractImpl::run() {
|
||||
}
|
||||
case RT_BridgeRetain: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.BridgeRetainList.push_back(CI);
|
||||
@@ -332,7 +331,7 @@ bool SwiftARCContractImpl::run() {
|
||||
}
|
||||
case RT_BridgeRelease: {
|
||||
auto *CI = cast<CallInst>(&Inst);
|
||||
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
|
||||
|
||||
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
|
||||
LocalEntry.BridgeReleaseList.push_back(CI);
|
||||
@@ -382,15 +381,12 @@ bool SwiftARCContractImpl::run() {
|
||||
}
|
||||
|
||||
bool SwiftARCContract::runOnFunction(Function &F) {
|
||||
RC = &getAnalysis<SwiftRCIdentity>();
|
||||
return SwiftARCContractImpl(F, RC).run();
|
||||
return SwiftARCContractImpl(F).run();
|
||||
}
|
||||
|
||||
char SwiftARCContract::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(SwiftARCContract,
|
||||
"swift-arc-contract", "Swift ARC contraction",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(SwiftRCIdentity)
|
||||
INITIALIZE_PASS_BEGIN(SwiftARCContract, "swift-arc-contract",
|
||||
"Swift ARC contraction", false, false)
|
||||
INITIALIZE_PASS_END(SwiftARCContract,
|
||||
"swift-arc-contract", "Swift ARC contraction",
|
||||
false, false)
|
||||
@@ -401,6 +397,17 @@ llvm::FunctionPass *swift::createSwiftARCContractPass() {
|
||||
}
|
||||
|
||||
void SwiftARCContract::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
|
||||
AU.addRequired<SwiftRCIdentity>();
|
||||
AU.setPreservesCFG();
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses
|
||||
SwiftARCContractPass::run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM) {
|
||||
bool changed = SwiftARCContractImpl(F).run();
|
||||
if (!changed)
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
PreservedAnalyses PA;
|
||||
PA.preserveSet<CFGAnalyses>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ DisableARCOpts("disable-llvm-arc-opts", llvm::cl::init(false));
|
||||
///
|
||||
/// This also does some trivial peep-hole optimizations as we go.
|
||||
static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
SwiftRCIdentity *RC) {
|
||||
SwiftRCIdentity &RC) {
|
||||
bool Changed = false;
|
||||
DenseSet<Value *> NativeRefs;
|
||||
DenseMap<Value *, TinyPtrVector<Instruction *>> UnknownObjectRetains;
|
||||
@@ -108,7 +108,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
break;
|
||||
case RT_Retain: {
|
||||
CallInst &CI = cast<CallInst>(Inst);
|
||||
Value *ArgVal = RC->getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
Value *ArgVal = RC.getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
// retain(null) is a no-op.
|
||||
if (isa<ConstantPointerNull>(ArgVal)) {
|
||||
CI.eraseFromParent();
|
||||
@@ -136,7 +136,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
}
|
||||
case RT_UnknownObjectRetain: {
|
||||
CallInst &CI = cast<CallInst>(Inst);
|
||||
Value *ArgVal = RC->getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
Value *ArgVal = RC.getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
// unknownObjectRetain(null) is a no-op.
|
||||
if (isa<ConstantPointerNull>(ArgVal)) {
|
||||
CI.eraseFromParent();
|
||||
@@ -166,7 +166,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
}
|
||||
case RT_Release: {
|
||||
CallInst &CI = cast<CallInst>(Inst);
|
||||
Value *ArgVal = RC->getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
Value *ArgVal = RC.getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
// release(null) is a no-op.
|
||||
if (isa<ConstantPointerNull>(ArgVal)) {
|
||||
CI.eraseFromParent();
|
||||
@@ -188,7 +188,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
}
|
||||
case RT_UnknownObjectRelease: {
|
||||
CallInst &CI = cast<CallInst>(Inst);
|
||||
Value *ArgVal = RC->getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
Value *ArgVal = RC.getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
// unknownObjectRelease(null) is a no-op.
|
||||
if (isa<ConstantPointerNull>(ArgVal)) {
|
||||
CI.eraseFromParent();
|
||||
@@ -213,7 +213,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
}
|
||||
case RT_ObjCRelease: {
|
||||
CallInst &CI = cast<CallInst>(Inst);
|
||||
Value *ArgVal = RC->getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
Value *ArgVal = RC.getSwiftRCIdentityRoot(CI.getArgOperand(0));
|
||||
// objc_release(null) is a noop, zap it.
|
||||
if (isa<ConstantPointerNull>(ArgVal)) {
|
||||
CI.eraseFromParent();
|
||||
@@ -263,10 +263,10 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
|
||||
/// access the released object. If we get to a retain or allocation of the
|
||||
/// object, zap both.
|
||||
static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
|
||||
SwiftRCIdentity *RC) {
|
||||
SwiftRCIdentity &RC) {
|
||||
// FIXME: Call classifier should identify the object for us. Too bad C++
|
||||
// doesn't have nice Swift-style enums.
|
||||
Value *ReleasedObject = RC->getSwiftRCIdentityRoot(Release.getArgOperand(0));
|
||||
Value *ReleasedObject = RC.getSwiftRCIdentityRoot(Release.getArgOperand(0));
|
||||
|
||||
BasicBlock::iterator BBI = Release.getIterator();
|
||||
|
||||
@@ -312,7 +312,7 @@ static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
|
||||
// API to drop multiple retain counts at once.
|
||||
CallInst &ThisRelease = cast<CallInst>(*BBI);
|
||||
Value *ThisReleasedObject = ThisRelease.getArgOperand(0);
|
||||
ThisReleasedObject = RC->getSwiftRCIdentityRoot(ThisReleasedObject);
|
||||
ThisReleasedObject = RC.getSwiftRCIdentityRoot(ThisReleasedObject);
|
||||
if (ThisReleasedObject == ReleasedObject) {
|
||||
//Release.dump(); ThisRelease.dump(); BB.getParent()->dump();
|
||||
++BBI;
|
||||
@@ -327,7 +327,7 @@ static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
|
||||
case RT_Retain: { // swift_retain(obj)
|
||||
CallInst &Retain = cast<CallInst>(*BBI);
|
||||
Value *RetainedObject = Retain.getArgOperand(0);
|
||||
RetainedObject = RC->getSwiftRCIdentityRoot(RetainedObject);
|
||||
RetainedObject = RC.getSwiftRCIdentityRoot(RetainedObject);
|
||||
|
||||
// Since we canonicalized earlier, we know that if our retain has any
|
||||
// uses, they were replaced already. This assertion documents this
|
||||
@@ -404,7 +404,6 @@ OutOfLoop:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Retain() Motion
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -416,10 +415,10 @@ OutOfLoop:
|
||||
/// NOTE: this handles both objc_retain and swift_retain.
|
||||
///
|
||||
static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB,
|
||||
SwiftRCIdentity *RC) {
|
||||
SwiftRCIdentity &RC) {
|
||||
// FIXME: Call classifier should identify the object for us. Too bad C++
|
||||
// doesn't have nice Swift-style enums.
|
||||
Value *RetainedObject = RC->getSwiftRCIdentityRoot(Retain.getArgOperand(0));
|
||||
Value *RetainedObject = RC.getSwiftRCIdentityRoot(Retain.getArgOperand(0));
|
||||
|
||||
BasicBlock::iterator BBI = Retain.getIterator(),
|
||||
BBE = BB.getTerminator()->getIterator();
|
||||
@@ -479,7 +478,7 @@ static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB,
|
||||
// it and the retain.
|
||||
CallInst &ThisRelease = cast<CallInst>(CurInst);
|
||||
Value *ThisReleasedObject = ThisRelease.getArgOperand(0);
|
||||
ThisReleasedObject = RC->getSwiftRCIdentityRoot(ThisReleasedObject);
|
||||
ThisReleasedObject = RC.getSwiftRCIdentityRoot(ThisReleasedObject);
|
||||
if (ThisReleasedObject == RetainedObject) {
|
||||
Retain.eraseFromParent();
|
||||
ThisRelease.eraseFromParent();
|
||||
@@ -527,7 +526,6 @@ OutOfLoop:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Store-Only Object Elimination
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -925,7 +923,7 @@ static void performRedundantCheckUnownedRemoval(BasicBlock &BB) {
|
||||
/// performGeneralOptimizations - This does a forward scan over basic blocks,
|
||||
/// looking for interesting local optimizations that can be done.
|
||||
static bool performGeneralOptimizations(Function &F, ARCEntryPointBuilder &B,
|
||||
SwiftRCIdentity *RC) {
|
||||
SwiftRCIdentity &RC) {
|
||||
bool Changed = false;
|
||||
|
||||
// TODO: This is a really trivial local algorithm. It could be much better.
|
||||
@@ -985,7 +983,6 @@ static bool performGeneralOptimizations(Function &F, ARCEntryPointBuilder &B,
|
||||
return Changed;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SwiftARCOpt Pass
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -996,7 +993,6 @@ INITIALIZE_PASS_BEGIN(SwiftARCOpt,
|
||||
"swift-llvm-arc-optimize", "Swift LLVM ARC optimization",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(SwiftAAWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(SwiftRCIdentity)
|
||||
INITIALIZE_PASS_END(SwiftARCOpt,
|
||||
"swift-llvm-arc-optimize", "Swift LLVM ARC optimization",
|
||||
false, false)
|
||||
@@ -1013,17 +1009,12 @@ SwiftARCOpt::SwiftARCOpt() : FunctionPass(ID) {
|
||||
|
||||
void SwiftARCOpt::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(&SwiftAAWrapperPass::ID);
|
||||
AU.addRequired<SwiftRCIdentity>();
|
||||
AU.setPreservesCFG();
|
||||
}
|
||||
|
||||
bool SwiftARCOpt::runOnFunction(Function &F) {
|
||||
if (DisableARCOpts)
|
||||
return false;
|
||||
|
||||
static bool runSwiftARCOpts(Function &F, SwiftRCIdentity &RC) {
|
||||
bool Changed = false;
|
||||
ARCEntryPointBuilder B(F);
|
||||
RC = &getAnalysis<SwiftRCIdentity>();
|
||||
|
||||
// First thing: canonicalize swift_retain and similar calls so that nothing
|
||||
// uses their result. This exposes the copy that the function does to the
|
||||
@@ -1041,3 +1032,26 @@ bool SwiftARCOpt::runOnFunction(Function &F) {
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
bool SwiftARCOpt::runOnFunction(Function &F) {
|
||||
if (DisableARCOpts)
|
||||
return false;
|
||||
|
||||
return runSwiftARCOpts(F, RC);
|
||||
}
|
||||
|
||||
PreservedAnalyses SwiftARCOptPass::run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM) {
|
||||
bool changed = false;
|
||||
|
||||
if (!DisableARCOpts)
|
||||
changed = runSwiftARCOpts(F, RC);
|
||||
|
||||
if (!changed) {
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
PreservedAnalyses PA;
|
||||
PA.preserveSet<CFGAnalyses>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
@@ -370,3 +370,12 @@ bool InlineTreePrinter::runOnModule(Module &M) {
|
||||
Tree.print(outs());
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::PreservedAnalyses
|
||||
swift::InlineTreePrinterPass::run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM) {
|
||||
InlineTree Tree;
|
||||
Tree.build(&M);
|
||||
Tree.print(outs());
|
||||
return llvm::PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
@@ -235,19 +235,15 @@ namespace {
|
||||
/// parameter. The original functions are replaced by thunks which call the
|
||||
/// merged function with the specific argument constants.
|
||||
///
|
||||
class SwiftMergeFunctions : public ModulePass {
|
||||
class SwiftMergeFunctions {
|
||||
public:
|
||||
static char ID;
|
||||
SwiftMergeFunctions()
|
||||
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)) {
|
||||
}
|
||||
SwiftMergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) {}
|
||||
|
||||
SwiftMergeFunctions(bool ptrAuthEnabled, unsigned ptrAuthKey)
|
||||
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)),
|
||||
ptrAuthOptionsSet(true), ptrAuthEnabled(ptrAuthEnabled),
|
||||
ptrAuthKey(ptrAuthKey) { }
|
||||
: FnTree(FunctionNodeCmp(&GlobalNumbers)), ptrAuthOptionsSet(true),
|
||||
ptrAuthEnabled(ptrAuthEnabled), ptrAuthKey(ptrAuthKey) {}
|
||||
|
||||
bool runOnModule(Module &M) override;
|
||||
bool runOnModule(Module &M);
|
||||
|
||||
private:
|
||||
struct FunctionEntry;
|
||||
@@ -531,20 +527,32 @@ private:
|
||||
const ParamInfos &Params, unsigned FuncIdx);
|
||||
};
|
||||
|
||||
class LegacySwiftMergeFunctions : public ModulePass {
|
||||
public:
|
||||
static char ID;
|
||||
SwiftMergeFunctions impl;
|
||||
|
||||
LegacySwiftMergeFunctions() : ModulePass(ID) {}
|
||||
|
||||
LegacySwiftMergeFunctions(bool ptrAuthEnabled, unsigned ptrAuthKey)
|
||||
: ModulePass(ID), impl(ptrAuthEnabled, ptrAuthKey) {}
|
||||
bool runOnModule(Module &M) override { return impl.runOnModule(M); }
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char SwiftMergeFunctions::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(SwiftMergeFunctions,
|
||||
"swift-merge-functions", "Swift merge function pass",
|
||||
false, false)
|
||||
INITIALIZE_PASS_END(SwiftMergeFunctions,
|
||||
"swift-merge-functions", "Swift merge function pass",
|
||||
false, false)
|
||||
char LegacySwiftMergeFunctions::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LegacySwiftMergeFunctions, "swift-merge-functions",
|
||||
"Swift merge function pass", false, false)
|
||||
INITIALIZE_PASS_END(LegacySwiftMergeFunctions, "swift-merge-functions",
|
||||
"Swift merge function pass", false, false)
|
||||
|
||||
llvm::ModulePass *swift::createSwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
||||
unsigned ptrAuthKey) {
|
||||
initializeSwiftMergeFunctionsPass(*llvm::PassRegistry::getPassRegistry());
|
||||
return new SwiftMergeFunctions(ptrAuthEnabled, ptrAuthKey);
|
||||
llvm::ModulePass *
|
||||
swift::createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
|
||||
unsigned ptrAuthKey) {
|
||||
initializeLegacySwiftMergeFunctionsPass(
|
||||
*llvm::PassRegistry::getPassRegistry());
|
||||
return new LegacySwiftMergeFunctions(ptrAuthEnabled, ptrAuthKey);
|
||||
}
|
||||
|
||||
bool SwiftMergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) {
|
||||
@@ -1330,3 +1338,14 @@ bool SwiftMergeFunctions::replaceDirectCallers(Function *Old, Function *New,
|
||||
assert(Old->use_empty() && "should have replaced all uses of old function");
|
||||
return Old->hasLocalLinkage();
|
||||
}
|
||||
|
||||
PreservedAnalyses SwiftMergeFunctionsPass::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
SwiftMergeFunctions helper(ptrAuthEnabled, ptrAuthKey);
|
||||
bool changed = helper.runOnModule(M);
|
||||
|
||||
if (!changed)
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
return PreservedAnalyses::none();
|
||||
}
|
||||
|
||||
@@ -75,6 +75,13 @@ void SwiftAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
}
|
||||
|
||||
AnalysisKey SwiftAA::Key;
|
||||
|
||||
SwiftAAResult SwiftAA::run(llvm::Function &F,
|
||||
llvm::FunctionAnalysisManager &AM) {
|
||||
return SwiftAAResult();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Top Level Entry Point
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
using namespace llvm;
|
||||
using swift::SwiftRCIdentity;
|
||||
|
||||
// Register this pass...
|
||||
char SwiftRCIdentity::ID = 0;
|
||||
INITIALIZE_PASS(SwiftRCIdentity, "swift-rc-identity",
|
||||
"Swift RC Identity Analysis", false, true)
|
||||
|
||||
bool SwiftRCIdentity::doInitialization(Module &M) {
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Value *
|
||||
SwiftRCIdentity::stripPointerCasts(llvm::Value *Val) {
|
||||
return Val->stripPointerCasts();
|
||||
@@ -87,8 +78,3 @@ SwiftRCIdentity::getSwiftRCIdentityRoot(llvm::Value *Val) {
|
||||
} while (true);
|
||||
return Val;
|
||||
}
|
||||
|
||||
llvm::ImmutablePass *swift::createSwiftRCIdentityPass() {
|
||||
initializeSwiftRCIdentityPass(*PassRegistry::getPassRegistry());
|
||||
return new SwiftRCIdentity();
|
||||
}
|
||||
|
||||
@@ -242,11 +242,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Register Swift Only Passes.
|
||||
initializeSwiftAAWrapperPassPass(Registry);
|
||||
initializeSwiftRCIdentityPass(Registry);
|
||||
initializeSwiftARCOptPass(Registry);
|
||||
initializeSwiftARCContractPass(Registry);
|
||||
initializeInlineTreePrinterPass(Registry);
|
||||
initializeSwiftMergeFunctionsPass(Registry);
|
||||
initializeLegacySwiftMergeFunctionsPass(Registry);
|
||||
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user