xref: /llvm-project/mlir/lib/Transforms/ControlFlowSink.cpp (revision fc367dfa6770fda4adc4e5de79846f22e7e4e215)
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 Scuttari void 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(&region->front(), region->front().begin());
523628febcSMogball         });
53572fa964SMogball   });
54572fa964SMogball }
55039b969bSMichele Scuttari 
createControlFlowSinkPass()56039b969bSMichele Scuttari std::unique_ptr<Pass> mlir::createControlFlowSinkPass() {
57039b969bSMichele Scuttari   return std::make_unique<ControlFlowSink>();
58039b969bSMichele Scuttari }
59