1//===- ControlFlowSinkUtils.h - ControlFlow Sink Utils ----------*- C++ -*-===//
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#ifndef MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
10#define MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
11
12#include "mlir/Support/LLVM.h"
13
14namespace mlir {
15
16class DominanceInfo;
17class Operation;
18class Region;
19class RegionBranchOpInterface;
20class RegionRange;
21
22/// Given a list of regions, perform control flow sinking on them. For each
23/// region, control-flow sinking moves operations that dominate the region but
24/// whose only users are in the region into the regions so that they aren't
25/// executed on paths where their results are not needed.
26///
27/// TODO: For the moment, this is a *simple* control-flow sink, i.e., no
28/// duplicating of ops. It should be made to accept a cost model to determine
29/// whether duplicating a particular op is profitable.
30///
31/// Example:
32///
33/// ```mlir
34/// %0 = arith.addi %arg0, %arg1
35/// scf.if %cond {
36/// scf.yield %0
37/// } else {
38/// scf.yield %arg2
39/// }
40/// ```
41///
42/// After control-flow sink:
43///
44/// ```mlir
45/// scf.if %cond {
46/// %0 = arith.addi %arg0, %arg1
47/// scf.yield %0
48/// } else {
49/// scf.yield %arg2
50/// }
51/// ```
52///
53/// Users must supply a callback `shouldMoveIntoRegion` that determines whether
54/// the given operation that only has users in the given operation should be
55/// moved into that region. If this returns true, `moveIntoRegion` is called on
56/// the same operation and region.
57///
58/// `moveIntoRegion` must move the operation into the region such that dominance
59/// of the operation is preserved; for example, by moving the operation to the
60/// start of the entry block. This ensures the preservation of SSA dominance of
61/// the operation's results.
62///
63/// Returns the number of operations sunk.
64size_t
65controlFlowSink(RegionRange regions, DominanceInfo &domInfo,
66 function_ref<bool(Operation *, Region *)> shouldMoveIntoRegion,
67 function_ref<void(Operation *, Region *)> moveIntoRegion);
68
69/// Populates `regions` with regions of the provided region branch op that are
70/// executed at most once at that are reachable given the current operands of
71/// the op. These regions can be passed to `controlFlowSink` to perform sinking
72/// on the regions of the operation.
73void getSinglyExecutedRegionsToSink(RegionBranchOpInterface branch,
74 SmallVectorImpl<Region *> &regions);
75
76} // namespace mlir
77
78#endif // MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
79

source code of mlir/include/mlir/Transforms/ControlFlowSinkUtils.h