MLIR  20.0.0git
ControlFlowSinkUtils.h
Go to the documentation of this file.
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 
14 namespace mlir {
15 
16 class DominanceInfo;
17 class Operation;
18 class Region;
19 class RegionBranchOpInterface;
20 class 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.
64 size_t
65 controlFlowSink(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.
73 void getSinglyExecutedRegionsToSink(RegionBranchOpInterface branch,
74  SmallVectorImpl<Region *> &regions);
75 
76 } // namespace mlir
77 
78 #endif // MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
Include the generated interface declarations.
void getSinglyExecutedRegionsToSink(RegionBranchOpInterface branch, SmallVectorImpl< Region * > &regions)
Populates regions with regions of the provided region branch op that are executed at most once at tha...
llvm::function_ref< Fn > function_ref
Definition: LLVM.h:152
size_t controlFlowSink(RegionRange regions, DominanceInfo &domInfo, function_ref< bool(Operation *, Region *)> shouldMoveIntoRegion, function_ref< void(Operation *, Region *)> moveIntoRegion)
Given a list of regions, perform control flow sinking on them.