//===--- ARCSequenceOpts.h --------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARCSEQUENCEOPTS_H #define SWIFT_SILOPTIMIZER_PASSMANAGER_ARCSEQUENCEOPTS_H #include "GlobalARCSequenceDataflow.h" #include "GlobalLoopARCSequenceDataflow.h" #include "ARCMatchingSet.h" #include "swift/SIL/SILValue.h" #include "swift/SILOptimizer/Utils/LoopUtils.h" #include "llvm/ADT/SetVector.h" namespace swift { class SILInstruction; class SILFunction; class AliasAnalysis; class PostOrderAnalysis; class LoopRegionFunctionInfo; class SILLoopInfo; class RCIdentityFunctionInfo; struct ARCPairingContext { SILFunction &F; BlotMapVector DecToIncStateMap; BlotMapVector IncToDecStateMap; RCIdentityFunctionInfo *RCIA; bool MadeChange = false; ARCPairingContext(SILFunction &F, RCIdentityFunctionInfo *RCIA) : F(F), DecToIncStateMap(), IncToDecStateMap(), RCIA(RCIA) {} bool performMatching(llvm::SmallVectorImpl &NewInsts, llvm::SmallVectorImpl &DeadInsts); void optimizeMatchingSet(ARCMatchingSet &MatchSet, llvm::SmallVectorImpl &NewInsts, llvm::SmallVectorImpl &DeadInsts); }; /// A composition of an ARCSequenceDataflowEvaluator and an /// ARCPairingContext. The evaluator performs top down/bottom up dataflows /// clearing the dataflow at loop boundaries. Then the results of the evaluator /// are placed into the ARCPairingContext and then the ARCPairingContext is used /// to pair retains/releases. struct BlockARCPairingContext { ARCPairingContext Context; ARCSequenceDataflowEvaluator Evaluator; BlockARCPairingContext(SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POTA, RCIdentityFunctionInfo *RCFI, EpilogueARCFunctionInfo *EAFI, ProgramTerminationFunctionInfo *PTFI) : Context(F, RCFI), Evaluator(F, AA, POTA, RCFI, EAFI, PTFI, Context.DecToIncStateMap, Context.IncToDecStateMap) {} bool run(bool FreezePostDomReleases) { bool NestingDetected = Evaluator.run(FreezePostDomReleases); Evaluator.clear(); llvm::SmallVector NewInsts; llvm::SmallVector DeadInsts; bool MatchedPair = Context.performMatching(NewInsts, DeadInsts); NewInsts.clear(); while (!DeadInsts.empty()) DeadInsts.pop_back_val()->eraseFromParent(); return NestingDetected && MatchedPair; } bool madeChange() const { return Context.MadeChange; } }; /// A composition of a LoopARCSequenceDataflowEvaluator and an /// ARCPairingContext. The loop nest is processed bottom up. For each loop, we /// run the evaluator on the loop and then use the ARCPairingContext to pair /// retains/releases and eliminate them. struct LoopARCPairingContext : SILLoopVisitor { ARCPairingContext Context; LoopARCSequenceDataflowEvaluator Evaluator; LoopRegionFunctionInfo *LRFI; SILLoopInfo *SLI; LoopARCPairingContext(SILFunction &F, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI, RCIdentityFunctionInfo *RCFI, EpilogueARCFunctionInfo *EAFI, ProgramTerminationFunctionInfo *PTFI) : SILLoopVisitor(&F, SLI), Context(F, RCFI), Evaluator(F, AA, LRFI, SLI, RCFI, EAFI, PTFI, Context.DecToIncStateMap, Context.IncToDecStateMap), LRFI(LRFI), SLI(SLI) {} bool process() { run(); if (!madeChange()) return false; run(); return true; } bool madeChange() const { return Context.MadeChange; } void runOnLoop(SILLoop *L) override; void runOnFunction(SILFunction *F) override; bool processRegion(const LoopRegion *R, bool FreezePostDomReleases, bool RecomputePostDomReleases); }; } // end swift namespace #endif