Update Swift's LLVM passes to include new pass manager versions

This commit is contained in:
Arnold Schwaighofer
2022-07-15 08:14:04 -07:00
parent 5c4c12a35d
commit 5c9eab0f6c
11 changed files with 202 additions and 99 deletions

View File

@@ -31,6 +31,11 @@ namespace swift {
bool invalidate(llvm::Function &, bool invalidate(llvm::Function &,
const llvm::PreservedAnalyses &) { return false; } const llvm::PreservedAnalyses &) { return false; }
bool invalidate(llvm::Function &, const llvm::PreservedAnalyses &,
llvm::FunctionAnalysisManager::Invalidator &) {
return false;
}
using AAResultBase::getModRefInfo; using AAResultBase::getModRefInfo;
llvm::ModRefInfo getModRefInfo(const llvm::CallBase *Call, llvm::ModRefInfo getModRefInfo(const llvm::CallBase *Call,
const llvm::MemoryLocation &Loc) { const llvm::MemoryLocation &Loc) {
@@ -57,27 +62,34 @@ namespace swift {
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override; 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: public:
static char ID; // Class identification, replacement for typeinfo using Result = SwiftAAResult;
SwiftRCIdentity() : ImmutablePass(ID) {}
SwiftAAResult run(llvm::Function &F, llvm::FunctionAnalysisManager &AM);
};
class SwiftRCIdentity {
public:
SwiftRCIdentity() {}
/// Returns the root of the RC-equivalent value for the given V. /// Returns the root of the RC-equivalent value for the given V.
llvm::Value *getSwiftRCIdentityRoot(llvm::Value *V); llvm::Value *getSwiftRCIdentityRoot(llvm::Value *V);
private: private:
enum { MaxRecursionDepth = 16 }; 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 *stripPointerCasts(llvm::Value *Val);
llvm::Value *stripReferenceForwarding(llvm::Value *Val); llvm::Value *stripReferenceForwarding(llvm::Value *Val);
}; };
class SwiftARCOpt : public llvm::FunctionPass { class SwiftARCOpt : public llvm::FunctionPass {
/// Swift RC Identity analysis. /// Swift RC Identity analysis.
SwiftRCIdentity *RC; SwiftRCIdentity RC;
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override; virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
virtual bool runOnFunction(llvm::Function &F) override; virtual bool runOnFunction(llvm::Function &F) override;
public: public:
@@ -85,9 +97,16 @@ namespace swift {
SwiftARCOpt(); SwiftARCOpt();
}; };
struct SwiftARCOptPass : public llvm::PassInfoMixin<SwiftARCOptPass> {
SwiftRCIdentity RC;
llvm::PreservedAnalyses run(llvm::Function &F,
llvm::FunctionAnalysisManager &AM);
};
class SwiftARCContract : public llvm::FunctionPass { class SwiftARCContract : public llvm::FunctionPass {
/// Swift RC Identity analysis. /// Swift RC Identity analysis.
SwiftRCIdentity *RC; SwiftRCIdentity RC;
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override; virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
virtual bool runOnFunction(llvm::Function &F) override; virtual bool runOnFunction(llvm::Function &F) override;
public: public:
@@ -95,6 +114,14 @@ namespace swift {
SwiftARCContract() : llvm::FunctionPass(ID) {} 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 { class InlineTreePrinter : public llvm::ModulePass {
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override; virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
virtual bool runOnModule(llvm::Module &M) override; virtual bool runOnModule(llvm::Module &M) override;
@@ -102,6 +129,30 @@ namespace swift {
static char ID; static char ID;
InlineTreePrinter() : llvm::ModulePass(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 } // end namespace swift
#endif #endif

View File

@@ -20,11 +20,10 @@ namespace llvm {
class PassRegistry; class PassRegistry;
void initializeSwiftAAWrapperPassPass(PassRegistry &); void initializeSwiftAAWrapperPassPass(PassRegistry &);
void initializeSwiftRCIdentityPass(PassRegistry &);
void initializeSwiftARCOptPass(PassRegistry &); void initializeSwiftARCOptPass(PassRegistry &);
void initializeSwiftARCContractPass(PassRegistry &); void initializeSwiftARCContractPass(PassRegistry &);
void initializeInlineTreePrinterPass(PassRegistry &); void initializeInlineTreePrinterPass(PassRegistry &);
void initializeSwiftMergeFunctionsPass(PassRegistry &); void initializeLegacySwiftMergeFunctionsPass(PassRegistry &);
void initializeSwiftDbgAddrBlockSplitterPass(PassRegistry &); void initializeSwiftDbgAddrBlockSplitterPass(PassRegistry &);
} }
@@ -32,11 +31,10 @@ namespace swift {
llvm::FunctionPass *createSwiftARCOptPass(); llvm::FunctionPass *createSwiftARCOptPass();
llvm::FunctionPass *createSwiftARCContractPass(); llvm::FunctionPass *createSwiftARCContractPass();
llvm::ModulePass *createInlineTreePrinterPass(); llvm::ModulePass *createInlineTreePrinterPass();
llvm::ModulePass *createSwiftMergeFunctionsPass(bool ptrAuthEnabled, llvm::ModulePass *createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
unsigned ptrAuthKey); unsigned ptrAuthKey);
llvm::FunctionPass *createSwiftDbgAddrBlockSplitter(); llvm::FunctionPass *createSwiftDbgAddrBlockSplitter();
llvm::ImmutablePass *createSwiftAAWrapperPass(); llvm::ImmutablePass *createSwiftAAWrapperPass();
llvm::ImmutablePass *createSwiftRCIdentityPass();
} // end namespace swift } // end namespace swift
#endif #endif

View File

@@ -290,7 +290,7 @@ performOptimizationsUsingLegacyPassManger(const IRGenOptions &Opts,
if (Builder.OptLevel > 0) { if (Builder.OptLevel > 0) {
const PointerAuthSchema &schema = Opts.PointerAuth.FunctionPointers; const PointerAuthSchema &schema = Opts.PointerAuth.FunctionPointers;
unsigned key = (schema.isEnabled() ? schema.getKey() : 0); unsigned key = (schema.isEnabled() ? schema.getKey() : 0);
PM.add(createSwiftMergeFunctionsPass(schema.isEnabled(), key)); PM.add(createLegacySwiftMergeFunctionsPass(schema.isEnabled(), key));
} }
}); });
} }

View File

@@ -36,7 +36,7 @@ struct SwiftDbgAddrBlockSplitter : FunctionPass {
} // namespace } // namespace
bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) { static bool split(Function &fn) {
SmallVector<Instruction *, 32> breakBlockPoints; SmallVector<Instruction *, 32> breakBlockPoints;
// If we are in the first block, // If we are in the first block,
@@ -65,6 +65,10 @@ bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
return madeChange; return madeChange;
} }
bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
return split(fn);
}
char SwiftDbgAddrBlockSplitter::ID = 0; char SwiftDbgAddrBlockSplitter::ID = 0;
INITIALIZE_PASS_BEGIN(SwiftDbgAddrBlockSplitter, INITIALIZE_PASS_BEGIN(SwiftDbgAddrBlockSplitter,
"swift-dbg-addr-block-splitter", "swift-dbg-addr-block-splitter",
@@ -79,3 +83,12 @@ llvm::FunctionPass *swift::createSwiftDbgAddrBlockSplitter() {
*llvm::PassRegistry::getPassRegistry()); *llvm::PassRegistry::getPassRegistry());
return new SwiftDbgAddrBlockSplitter(); 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();
}

View File

@@ -64,7 +64,7 @@ class SwiftARCContractImpl {
bool Changed; bool Changed;
/// Swift RC Identity. /// Swift RC Identity.
SwiftRCIdentity *RC; SwiftRCIdentity RC;
/// The function that we are processing. /// The function that we are processing.
Function &F; Function &F;
@@ -72,8 +72,7 @@ class SwiftARCContractImpl {
/// The entry point builder that is used to construct ARC entry points. /// The entry point builder that is used to construct ARC entry points.
ARCEntryPointBuilder B; ARCEntryPointBuilder B;
public: public:
SwiftARCContractImpl(Function &InF, SwiftRCIdentity *InRC) SwiftARCContractImpl(Function &InF) : Changed(false), F(InF), B(F) {}
: Changed(false), RC(InRC), F(InF), B(F) {}
// The top level run routine of the pass. // The top level run routine of the pass.
bool run(); bool run();
@@ -109,7 +108,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
break; 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 // Replace all uses of the retain instructions with our new retainN and
// then delete them. // then delete them.
@@ -135,7 +134,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
break; break;
} }
} }
B.createReleaseN(RC->getSwiftRCIdentityRoot(O), ReleaseList.size(), RI); B.createReleaseN(RC.getSwiftRCIdentityRoot(O), ReleaseList.size(), RI);
// Remove all old release instructions. // Remove all old release instructions.
for (auto *Inst : ReleaseList) { for (auto *Inst : ReleaseList) {
@@ -159,7 +158,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
break; break;
} }
} }
B.createUnknownObjectRetainN(RC->getSwiftRCIdentityRoot(O), B.createUnknownObjectRetainN(RC.getSwiftRCIdentityRoot(O),
UnknownObjectRetainList.size(), RI); UnknownObjectRetainList.size(), RI);
// Replace all uses of the retain instructions with our new retainN and // Replace all uses of the retain instructions with our new retainN and
@@ -187,7 +186,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
break; break;
} }
} }
B.createUnknownObjectReleaseN(RC->getSwiftRCIdentityRoot(O), B.createUnknownObjectReleaseN(RC.getSwiftRCIdentityRoot(O),
UnknownObjectReleaseList.size(), RI); UnknownObjectReleaseList.size(), RI);
// Remove all old release instructions. // Remove all old release instructions.
@@ -214,7 +213,7 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
} }
} }
// Bridge retain may modify the input reference before forwarding it. // 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); BridgeRetainList.size(), RI);
// Remove all old retain instructions. // Remove all old retain instructions.
@@ -246,8 +245,8 @@ performRRNOptimization(DenseMap<Value *, LocalState> &PtrToLocalStateMap) {
break; break;
} }
} }
B.createBridgeReleaseN(RC->getSwiftRCIdentityRoot(O), B.createBridgeReleaseN(RC.getSwiftRCIdentityRoot(O),
BridgeReleaseList.size(), RI); BridgeReleaseList.size(), RI);
// Remove all old release instructions. // Remove all old release instructions.
for (auto *Inst : BridgeReleaseList) { for (auto *Inst : BridgeReleaseList) {
@@ -290,7 +289,7 @@ bool SwiftARCContractImpl::run() {
continue; continue;
case RT_Retain: { case RT_Retain: {
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.RetainList.push_back(CI); LocalEntry.RetainList.push_back(CI);
@@ -298,7 +297,7 @@ bool SwiftARCContractImpl::run() {
} }
case RT_UnknownObjectRetain: { case RT_UnknownObjectRetain: {
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.UnknownObjectRetainList.push_back(CI); LocalEntry.UnknownObjectRetainList.push_back(CI);
@@ -307,7 +306,7 @@ bool SwiftARCContractImpl::run() {
case RT_Release: { case RT_Release: {
// Stash any releases that we see. // Stash any releases that we see.
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.ReleaseList.push_back(CI); LocalEntry.ReleaseList.push_back(CI);
@@ -316,7 +315,7 @@ bool SwiftARCContractImpl::run() {
case RT_UnknownObjectRelease: { case RT_UnknownObjectRelease: {
// Stash any releases that we see. // Stash any releases that we see.
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.UnknownObjectReleaseList.push_back(CI); LocalEntry.UnknownObjectReleaseList.push_back(CI);
@@ -324,7 +323,7 @@ bool SwiftARCContractImpl::run() {
} }
case RT_BridgeRetain: { case RT_BridgeRetain: {
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.BridgeRetainList.push_back(CI); LocalEntry.BridgeRetainList.push_back(CI);
@@ -332,7 +331,7 @@ bool SwiftARCContractImpl::run() {
} }
case RT_BridgeRelease: { case RT_BridgeRelease: {
auto *CI = cast<CallInst>(&Inst); auto *CI = cast<CallInst>(&Inst);
auto *ArgVal = RC->getSwiftRCIdentityRoot(CI->getArgOperand(0)); auto *ArgVal = RC.getSwiftRCIdentityRoot(CI->getArgOperand(0));
LocalState &LocalEntry = PtrToLocalStateMap[ArgVal]; LocalState &LocalEntry = PtrToLocalStateMap[ArgVal];
LocalEntry.BridgeReleaseList.push_back(CI); LocalEntry.BridgeReleaseList.push_back(CI);
@@ -382,15 +381,12 @@ bool SwiftARCContractImpl::run() {
} }
bool SwiftARCContract::runOnFunction(Function &F) { bool SwiftARCContract::runOnFunction(Function &F) {
RC = &getAnalysis<SwiftRCIdentity>(); return SwiftARCContractImpl(F).run();
return SwiftARCContractImpl(F, RC).run();
} }
char SwiftARCContract::ID = 0; char SwiftARCContract::ID = 0;
INITIALIZE_PASS_BEGIN(SwiftARCContract, INITIALIZE_PASS_BEGIN(SwiftARCContract, "swift-arc-contract",
"swift-arc-contract", "Swift ARC contraction", "Swift ARC contraction", false, false)
false, false)
INITIALIZE_PASS_DEPENDENCY(SwiftRCIdentity)
INITIALIZE_PASS_END(SwiftARCContract, INITIALIZE_PASS_END(SwiftARCContract,
"swift-arc-contract", "Swift ARC contraction", "swift-arc-contract", "Swift ARC contraction",
false, false) false, false)
@@ -401,6 +397,17 @@ llvm::FunctionPass *swift::createSwiftARCContractPass() {
} }
void SwiftARCContract::getAnalysisUsage(llvm::AnalysisUsage &AU) const { void SwiftARCContract::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
AU.addRequired<SwiftRCIdentity>();
AU.setPreservesCFG(); 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;
}

View File

@@ -75,7 +75,7 @@ DisableARCOpts("disable-llvm-arc-opts", llvm::cl::init(false));
/// ///
/// This also does some trivial peep-hole optimizations as we go. /// This also does some trivial peep-hole optimizations as we go.
static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B, static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
SwiftRCIdentity *RC) { SwiftRCIdentity &RC) {
bool Changed = false; bool Changed = false;
DenseSet<Value *> NativeRefs; DenseSet<Value *> NativeRefs;
DenseMap<Value *, TinyPtrVector<Instruction *>> UnknownObjectRetains; DenseMap<Value *, TinyPtrVector<Instruction *>> UnknownObjectRetains;
@@ -108,7 +108,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
break; break;
case RT_Retain: { case RT_Retain: {
CallInst &CI = cast<CallInst>(Inst); 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. // retain(null) is a no-op.
if (isa<ConstantPointerNull>(ArgVal)) { if (isa<ConstantPointerNull>(ArgVal)) {
CI.eraseFromParent(); CI.eraseFromParent();
@@ -136,7 +136,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
} }
case RT_UnknownObjectRetain: { case RT_UnknownObjectRetain: {
CallInst &CI = cast<CallInst>(Inst); 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. // unknownObjectRetain(null) is a no-op.
if (isa<ConstantPointerNull>(ArgVal)) { if (isa<ConstantPointerNull>(ArgVal)) {
CI.eraseFromParent(); CI.eraseFromParent();
@@ -166,7 +166,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
} }
case RT_Release: { case RT_Release: {
CallInst &CI = cast<CallInst>(Inst); 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. // release(null) is a no-op.
if (isa<ConstantPointerNull>(ArgVal)) { if (isa<ConstantPointerNull>(ArgVal)) {
CI.eraseFromParent(); CI.eraseFromParent();
@@ -188,7 +188,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
} }
case RT_UnknownObjectRelease: { case RT_UnknownObjectRelease: {
CallInst &CI = cast<CallInst>(Inst); 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. // unknownObjectRelease(null) is a no-op.
if (isa<ConstantPointerNull>(ArgVal)) { if (isa<ConstantPointerNull>(ArgVal)) {
CI.eraseFromParent(); CI.eraseFromParent();
@@ -213,7 +213,7 @@ static bool canonicalizeInputFunction(Function &F, ARCEntryPointBuilder &B,
} }
case RT_ObjCRelease: { case RT_ObjCRelease: {
CallInst &CI = cast<CallInst>(Inst); 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. // objc_release(null) is a noop, zap it.
if (isa<ConstantPointerNull>(ArgVal)) { if (isa<ConstantPointerNull>(ArgVal)) {
CI.eraseFromParent(); 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 /// access the released object. If we get to a retain or allocation of the
/// object, zap both. /// object, zap both.
static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB, static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
SwiftRCIdentity *RC) { SwiftRCIdentity &RC) {
// FIXME: Call classifier should identify the object for us. Too bad C++ // FIXME: Call classifier should identify the object for us. Too bad C++
// doesn't have nice Swift-style enums. // 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(); BasicBlock::iterator BBI = Release.getIterator();
@@ -312,7 +312,7 @@ static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
// API to drop multiple retain counts at once. // API to drop multiple retain counts at once.
CallInst &ThisRelease = cast<CallInst>(*BBI); CallInst &ThisRelease = cast<CallInst>(*BBI);
Value *ThisReleasedObject = ThisRelease.getArgOperand(0); Value *ThisReleasedObject = ThisRelease.getArgOperand(0);
ThisReleasedObject = RC->getSwiftRCIdentityRoot(ThisReleasedObject); ThisReleasedObject = RC.getSwiftRCIdentityRoot(ThisReleasedObject);
if (ThisReleasedObject == ReleasedObject) { if (ThisReleasedObject == ReleasedObject) {
//Release.dump(); ThisRelease.dump(); BB.getParent()->dump(); //Release.dump(); ThisRelease.dump(); BB.getParent()->dump();
++BBI; ++BBI;
@@ -327,7 +327,7 @@ static bool performLocalReleaseMotion(CallInst &Release, BasicBlock &BB,
case RT_Retain: { // swift_retain(obj) case RT_Retain: { // swift_retain(obj)
CallInst &Retain = cast<CallInst>(*BBI); CallInst &Retain = cast<CallInst>(*BBI);
Value *RetainedObject = Retain.getArgOperand(0); 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 // Since we canonicalized earlier, we know that if our retain has any
// uses, they were replaced already. This assertion documents this // uses, they were replaced already. This assertion documents this
@@ -404,7 +404,6 @@ OutOfLoop:
return false; return false;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Retain() Motion // Retain() Motion
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -416,10 +415,10 @@ OutOfLoop:
/// NOTE: this handles both objc_retain and swift_retain. /// NOTE: this handles both objc_retain and swift_retain.
/// ///
static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB, static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB,
SwiftRCIdentity *RC) { SwiftRCIdentity &RC) {
// FIXME: Call classifier should identify the object for us. Too bad C++ // FIXME: Call classifier should identify the object for us. Too bad C++
// doesn't have nice Swift-style enums. // 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(), BasicBlock::iterator BBI = Retain.getIterator(),
BBE = BB.getTerminator()->getIterator(); BBE = BB.getTerminator()->getIterator();
@@ -479,7 +478,7 @@ static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB,
// it and the retain. // it and the retain.
CallInst &ThisRelease = cast<CallInst>(CurInst); CallInst &ThisRelease = cast<CallInst>(CurInst);
Value *ThisReleasedObject = ThisRelease.getArgOperand(0); Value *ThisReleasedObject = ThisRelease.getArgOperand(0);
ThisReleasedObject = RC->getSwiftRCIdentityRoot(ThisReleasedObject); ThisReleasedObject = RC.getSwiftRCIdentityRoot(ThisReleasedObject);
if (ThisReleasedObject == RetainedObject) { if (ThisReleasedObject == RetainedObject) {
Retain.eraseFromParent(); Retain.eraseFromParent();
ThisRelease.eraseFromParent(); ThisRelease.eraseFromParent();
@@ -527,7 +526,6 @@ OutOfLoop:
return false; return false;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Store-Only Object Elimination // Store-Only Object Elimination
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -925,7 +923,7 @@ static void performRedundantCheckUnownedRemoval(BasicBlock &BB) {
/// performGeneralOptimizations - This does a forward scan over basic blocks, /// performGeneralOptimizations - This does a forward scan over basic blocks,
/// looking for interesting local optimizations that can be done. /// looking for interesting local optimizations that can be done.
static bool performGeneralOptimizations(Function &F, ARCEntryPointBuilder &B, static bool performGeneralOptimizations(Function &F, ARCEntryPointBuilder &B,
SwiftRCIdentity *RC) { SwiftRCIdentity &RC) {
bool Changed = false; bool Changed = false;
// TODO: This is a really trivial local algorithm. It could be much better. // 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; return Changed;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SwiftARCOpt Pass // SwiftARCOpt Pass
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -996,7 +993,6 @@ INITIALIZE_PASS_BEGIN(SwiftARCOpt,
"swift-llvm-arc-optimize", "Swift LLVM ARC optimization", "swift-llvm-arc-optimize", "Swift LLVM ARC optimization",
false, false) false, false)
INITIALIZE_PASS_DEPENDENCY(SwiftAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(SwiftAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SwiftRCIdentity)
INITIALIZE_PASS_END(SwiftARCOpt, INITIALIZE_PASS_END(SwiftARCOpt,
"swift-llvm-arc-optimize", "Swift LLVM ARC optimization", "swift-llvm-arc-optimize", "Swift LLVM ARC optimization",
false, false) false, false)
@@ -1013,17 +1009,12 @@ SwiftARCOpt::SwiftARCOpt() : FunctionPass(ID) {
void SwiftARCOpt::getAnalysisUsage(llvm::AnalysisUsage &AU) const { void SwiftARCOpt::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
AU.addRequiredID(&SwiftAAWrapperPass::ID); AU.addRequiredID(&SwiftAAWrapperPass::ID);
AU.addRequired<SwiftRCIdentity>();
AU.setPreservesCFG(); AU.setPreservesCFG();
} }
bool SwiftARCOpt::runOnFunction(Function &F) { static bool runSwiftARCOpts(Function &F, SwiftRCIdentity &RC) {
if (DisableARCOpts)
return false;
bool Changed = false; bool Changed = false;
ARCEntryPointBuilder B(F); ARCEntryPointBuilder B(F);
RC = &getAnalysis<SwiftRCIdentity>();
// First thing: canonicalize swift_retain and similar calls so that nothing // First thing: canonicalize swift_retain and similar calls so that nothing
// uses their result. This exposes the copy that the function does to the // uses their result. This exposes the copy that the function does to the
@@ -1041,3 +1032,26 @@ bool SwiftARCOpt::runOnFunction(Function &F) {
return Changed; 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;
}

View File

@@ -370,3 +370,12 @@ bool InlineTreePrinter::runOnModule(Module &M) {
Tree.print(outs()); Tree.print(outs());
return false; 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();
}

View File

@@ -235,19 +235,15 @@ namespace {
/// parameter. The original functions are replaced by thunks which call the /// parameter. The original functions are replaced by thunks which call the
/// merged function with the specific argument constants. /// merged function with the specific argument constants.
/// ///
class SwiftMergeFunctions : public ModulePass { class SwiftMergeFunctions {
public: public:
static char ID; SwiftMergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) {}
SwiftMergeFunctions()
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)) {
}
SwiftMergeFunctions(bool ptrAuthEnabled, unsigned ptrAuthKey) SwiftMergeFunctions(bool ptrAuthEnabled, unsigned ptrAuthKey)
: ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)), : FnTree(FunctionNodeCmp(&GlobalNumbers)), ptrAuthOptionsSet(true),
ptrAuthOptionsSet(true), ptrAuthEnabled(ptrAuthEnabled), ptrAuthEnabled(ptrAuthEnabled), ptrAuthKey(ptrAuthKey) {}
ptrAuthKey(ptrAuthKey) { }
bool runOnModule(Module &M) override; bool runOnModule(Module &M);
private: private:
struct FunctionEntry; struct FunctionEntry;
@@ -531,20 +527,32 @@ private:
const ParamInfos &Params, unsigned FuncIdx); 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 } // end anonymous namespace
char SwiftMergeFunctions::ID = 0; char LegacySwiftMergeFunctions::ID = 0;
INITIALIZE_PASS_BEGIN(SwiftMergeFunctions, INITIALIZE_PASS_BEGIN(LegacySwiftMergeFunctions, "swift-merge-functions",
"swift-merge-functions", "Swift merge function pass", "Swift merge function pass", false, false)
false, false) INITIALIZE_PASS_END(LegacySwiftMergeFunctions, "swift-merge-functions",
INITIALIZE_PASS_END(SwiftMergeFunctions, "Swift merge function pass", false, false)
"swift-merge-functions", "Swift merge function pass",
false, false)
llvm::ModulePass *swift::createSwiftMergeFunctionsPass(bool ptrAuthEnabled, llvm::ModulePass *
unsigned ptrAuthKey) { swift::createLegacySwiftMergeFunctionsPass(bool ptrAuthEnabled,
initializeSwiftMergeFunctionsPass(*llvm::PassRegistry::getPassRegistry()); unsigned ptrAuthKey) {
return new SwiftMergeFunctions(ptrAuthEnabled, ptrAuthKey); initializeLegacySwiftMergeFunctionsPass(
*llvm::PassRegistry::getPassRegistry());
return new LegacySwiftMergeFunctions(ptrAuthEnabled, ptrAuthKey);
} }
bool SwiftMergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { 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"); assert(Old->use_empty() && "should have replaced all uses of old function");
return Old->hasLocalLinkage(); 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();
}

View File

@@ -75,6 +75,13 @@ void SwiftAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetLibraryInfoWrapperPass>(); AU.addRequired<TargetLibraryInfoWrapperPass>();
} }
AnalysisKey SwiftAA::Key;
SwiftAAResult SwiftAA::run(llvm::Function &F,
llvm::FunctionAnalysisManager &AM) {
return SwiftAAResult();
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Top Level Entry Point // Top Level Entry Point
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@@ -17,15 +17,6 @@
using namespace llvm; using namespace llvm;
using swift::SwiftRCIdentity; 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 * llvm::Value *
SwiftRCIdentity::stripPointerCasts(llvm::Value *Val) { SwiftRCIdentity::stripPointerCasts(llvm::Value *Val) {
return Val->stripPointerCasts(); return Val->stripPointerCasts();
@@ -87,8 +78,3 @@ SwiftRCIdentity::getSwiftRCIdentityRoot(llvm::Value *Val) {
} while (true); } while (true);
return Val; return Val;
} }
llvm::ImmutablePass *swift::createSwiftRCIdentityPass() {
initializeSwiftRCIdentityPass(*PassRegistry::getPassRegistry());
return new SwiftRCIdentity();
}

View File

@@ -242,11 +242,10 @@ int main(int argc, char **argv) {
// Register Swift Only Passes. // Register Swift Only Passes.
initializeSwiftAAWrapperPassPass(Registry); initializeSwiftAAWrapperPassPass(Registry);
initializeSwiftRCIdentityPass(Registry);
initializeSwiftARCOptPass(Registry); initializeSwiftARCOptPass(Registry);
initializeSwiftARCContractPass(Registry); initializeSwiftARCContractPass(Registry);
initializeInlineTreePrinterPass(Registry); initializeInlineTreePrinterPass(Registry);
initializeSwiftMergeFunctionsPass(Registry); initializeLegacySwiftMergeFunctionsPass(Registry);
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n"); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");