1572fa964SMogball //===- ControlFlowSink.cpp - Code to perform control-flow sinking ---------===// 2572fa964SMogball // 3572fa964SMogball // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4572fa964SMogball // See https://llvm.org/LICENSE.txt for license information. 5572fa964SMogball // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6572fa964SMogball // 7572fa964SMogball //===----------------------------------------------------------------------===// 8572fa964SMogball // 9572fa964SMogball // This file implements a basic control-flow sink pass. Control-flow sinking 10572fa964SMogball // moves operations whose only uses are in conditionally-executed blocks in to 11572fa964SMogball // those blocks so that they aren't executed on paths where their results are 12572fa964SMogball // not needed. 13572fa964SMogball // 14572fa964SMogball //===----------------------------------------------------------------------===// 15572fa964SMogball 1667d0d7acSMichele Scuttari #include "mlir/Transforms/Passes.h" 1767d0d7acSMichele Scuttari 18572fa964SMogball #include "mlir/IR/Dominance.h" 19572fa964SMogball #include "mlir/Interfaces/ControlFlowInterfaces.h" 2036d3efeaSRiver Riddle #include "mlir/Interfaces/SideEffectInterfaces.h" 21a70aa7bbSRiver Riddle #include "mlir/Transforms/ControlFlowSinkUtils.h" 22572fa964SMogball 2367d0d7acSMichele Scuttari namespace mlir { 2467d0d7acSMichele Scuttari #define GEN_PASS_DEF_CONTROLFLOWSINK 2567d0d7acSMichele Scuttari #include "mlir/Transforms/Passes.h.inc" 2667d0d7acSMichele Scuttari } // namespace mlir 2767d0d7acSMichele Scuttari 28572fa964SMogball using namespace mlir; 29572fa964SMogball 30572fa964SMogball namespace { 313628febcSMogball /// A control-flow sink pass. 3267d0d7acSMichele Scuttari struct ControlFlowSink : public impl::ControlFlowSinkBase<ControlFlowSink> { 33572fa964SMogball void runOnOperation() override; 34572fa964SMogball }; 35572fa964SMogball } // end anonymous namespace 36572fa964SMogball runOnOperation()37039b969bSMichele Scuttarivoid ControlFlowSink::runOnOperation() { 38572fa964SMogball auto &domInfo = getAnalysis<DominanceInfo>(); 39572fa964SMogball getOperation()->walk([&](RegionBranchOpInterface branch) { 40572fa964SMogball SmallVector<Region *> regionsToSink; 413628febcSMogball // Get the regions are that known to be executed at most once. 42572fa964SMogball getSinglyExecutedRegionsToSink(branch, regionsToSink); 433628febcSMogball // Sink side-effect free operations. 44b73f1d2cSMogball numSunk = controlFlowSink( 45b73f1d2cSMogball regionsToSink, domInfo, 46*86771d0bSSanjoy Das [](Operation *op, Region *) { return isMemoryEffectFree(op); }, 47b73f1d2cSMogball [](Operation *op, Region *region) { 48b73f1d2cSMogball // Move the operation to the beginning of the region's entry block. 49b73f1d2cSMogball // This guarantees the preservation of SSA dominance of all of the 50b73f1d2cSMogball // operation's uses are in the region. 51b73f1d2cSMogball op->moveBefore(®ion->front(), region->front().begin()); 523628febcSMogball }); 53572fa964SMogball }); 54572fa964SMogball } 55039b969bSMichele Scuttari createControlFlowSinkPass()56039b969bSMichele Scuttaristd::unique_ptr<Pass> mlir::createControlFlowSinkPass() { 57039b969bSMichele Scuttari return std::make_unique<ControlFlowSink>(); 58039b969bSMichele Scuttari } 59