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 16572fa964SMogball #include "PassDetail.h" 17572fa964SMogball #include "mlir/IR/Dominance.h" 18572fa964SMogball #include "mlir/Interfaces/ControlFlowInterfaces.h" 1936d3efeaSRiver Riddle #include "mlir/Interfaces/SideEffectInterfaces.h" 20a70aa7bbSRiver Riddle #include "mlir/Transforms/ControlFlowSinkUtils.h" 21572fa964SMogball #include "mlir/Transforms/Passes.h" 22*fa26c7ffSMogball #include "mlir/Transforms/SideEffectUtils.h" 23572fa964SMogball 24572fa964SMogball using namespace mlir; 25572fa964SMogball 26572fa964SMogball namespace { 273628febcSMogball /// A control-flow sink pass. 28572fa964SMogball struct ControlFlowSink : public ControlFlowSinkBase<ControlFlowSink> { 29572fa964SMogball void runOnOperation() override; 30572fa964SMogball }; 31572fa964SMogball } // end anonymous namespace 32572fa964SMogball runOnOperation()33572fa964SMogballvoid ControlFlowSink::runOnOperation() { 34572fa964SMogball auto &domInfo = getAnalysis<DominanceInfo>(); 35572fa964SMogball getOperation()->walk([&](RegionBranchOpInterface branch) { 36572fa964SMogball SmallVector<Region *> regionsToSink; 373628febcSMogball // Get the regions are that known to be executed at most once. 38572fa964SMogball getSinglyExecutedRegionsToSink(branch, regionsToSink); 393628febcSMogball // Sink side-effect free operations. 40b73f1d2cSMogball numSunk = controlFlowSink( 41b73f1d2cSMogball regionsToSink, domInfo, 42b73f1d2cSMogball [](Operation *op, Region *) { return isSideEffectFree(op); }, 43b73f1d2cSMogball [](Operation *op, Region *region) { 44b73f1d2cSMogball // Move the operation to the beginning of the region's entry block. 45b73f1d2cSMogball // This guarantees the preservation of SSA dominance of all of the 46b73f1d2cSMogball // operation's uses are in the region. 47b73f1d2cSMogball op->moveBefore(®ion->front(), region->front().begin()); 483628febcSMogball }); 49572fa964SMogball }); 50572fa964SMogball } 51572fa964SMogball createControlFlowSinkPass()52572fa964SMogballstd::unique_ptr<Pass> mlir::createControlFlowSinkPass() { 53572fa964SMogball return std::make_unique<ControlFlowSink>(); 54572fa964SMogball } 55