1 //===- ControlFlowSink.cpp - Code to perform control-flow sinking ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements a basic control-flow sink pass. Control-flow sinking 10 // moves operations whose only uses are in conditionally-executed blocks in to 11 // those blocks so that they aren't executed on paths where their results are 12 // not needed. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "PassDetail.h" 17 #include "mlir/IR/Dominance.h" 18 #include "mlir/Interfaces/ControlFlowInterfaces.h" 19 #include "mlir/Interfaces/SideEffectInterfaces.h" 20 #include "mlir/Transforms/ControlFlowSinkUtils.h" 21 #include "mlir/Transforms/Passes.h" 22 #include "mlir/Transforms/SideEffectUtils.h" 23 24 using namespace mlir; 25 26 namespace { 27 /// A control-flow sink pass. 28 struct ControlFlowSink : public ControlFlowSinkBase<ControlFlowSink> { 29 void runOnOperation() override; 30 }; 31 } // end anonymous namespace 32 runOnOperation()33void ControlFlowSink::runOnOperation() { 34 auto &domInfo = getAnalysis<DominanceInfo>(); 35 getOperation()->walk([&](RegionBranchOpInterface branch) { 36 SmallVector<Region *> regionsToSink; 37 // Get the regions are that known to be executed at most once. 38 getSinglyExecutedRegionsToSink(branch, regionsToSink); 39 // Sink side-effect free operations. 40 numSunk = controlFlowSink( 41 regionsToSink, domInfo, 42 [](Operation *op, Region *) { return isSideEffectFree(op); }, 43 [](Operation *op, Region *region) { 44 // Move the operation to the beginning of the region's entry block. 45 // This guarantees the preservation of SSA dominance of all of the 46 // operation's uses are in the region. 47 op->moveBefore(®ion->front(), region->front().begin()); 48 }); 49 }); 50 } 51 createControlFlowSinkPass()52std::unique_ptr<Pass> mlir::createControlFlowSinkPass() { 53 return std::make_unique<ControlFlowSink>(); 54 } 55