59 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements a basic control-flow sink pass. Control-flow sinking10// moves operations whose only uses are in conditionally-executed blocks in to11// those blocks so that they aren't executed on paths where their results are12// not needed.13//14//===----------------------------------------------------------------------===//15 16#include "mlir/Transforms/Passes.h"17 18#include "mlir/IR/Dominance.h"19#include "mlir/Interfaces/ControlFlowInterfaces.h"20#include "mlir/Interfaces/SideEffectInterfaces.h"21#include "mlir/Transforms/ControlFlowSinkUtils.h"22 23namespace mlir {24#define GEN_PASS_DEF_CONTROLFLOWSINK25#include "mlir/Transforms/Passes.h.inc"26} // namespace mlir27 28using namespace mlir;29 30namespace {31/// A control-flow sink pass.32struct ControlFlowSink : public impl::ControlFlowSinkBase<ControlFlowSink> {33 void runOnOperation() override;34};35} // end anonymous namespace36 37void ControlFlowSink::runOnOperation() {38 auto &domInfo = getAnalysis<DominanceInfo>();39 getOperation()->walk([&](RegionBranchOpInterface branch) {40 SmallVector<Region *> regionsToSink;41 // Get the regions are that known to be executed at most once.42 getSinglyExecutedRegionsToSink(branch, regionsToSink);43 // Sink side-effect free operations.44 numSunk = controlFlowSink(45 regionsToSink, domInfo,46 [](Operation *op, Region *) { return isMemoryEffectFree(op); },47 [](Operation *op, Region *region) {48 // Move the operation to the beginning of the region's entry block.49 // This guarantees the preservation of SSA dominance of all of the50 // operation's uses are in the region.51 op->moveBefore(®ion->front(), region->front().begin());52 });53 });54}55 56std::unique_ptr<Pass> mlir::createControlFlowSinkPass() {57 return std::make_unique<ControlFlowSink>();58}59