79 lines
2.7 KiB
C++
79 lines
2.7 KiB
C++
//===- ControlFlowSinkUtils.h - ControlFlow Sink Utils ----------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
|
|
#define MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
|
|
|
|
#include "mlir/Support/LLVM.h"
|
|
|
|
namespace mlir {
|
|
|
|
class DominanceInfo;
|
|
class Operation;
|
|
class Region;
|
|
class RegionBranchOpInterface;
|
|
class RegionRange;
|
|
|
|
/// Given a list of regions, perform control flow sinking on them. For each
|
|
/// region, control-flow sinking moves operations that dominate the region but
|
|
/// whose only users are in the region into the regions so that they aren't
|
|
/// executed on paths where their results are not needed.
|
|
///
|
|
/// TODO: For the moment, this is a *simple* control-flow sink, i.e., no
|
|
/// duplicating of ops. It should be made to accept a cost model to determine
|
|
/// whether duplicating a particular op is profitable.
|
|
///
|
|
/// Example:
|
|
///
|
|
/// ```mlir
|
|
/// %0 = arith.addi %arg0, %arg1
|
|
/// scf.if %cond {
|
|
/// scf.yield %0
|
|
/// } else {
|
|
/// scf.yield %arg2
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// After control-flow sink:
|
|
///
|
|
/// ```mlir
|
|
/// scf.if %cond {
|
|
/// %0 = arith.addi %arg0, %arg1
|
|
/// scf.yield %0
|
|
/// } else {
|
|
/// scf.yield %arg2
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Users must supply a callback `shouldMoveIntoRegion` that determines whether
|
|
/// the given operation that only has users in the given operation should be
|
|
/// moved into that region. If this returns true, `moveIntoRegion` is called on
|
|
/// the same operation and region.
|
|
///
|
|
/// `moveIntoRegion` must move the operation into the region such that dominance
|
|
/// of the operation is preserved; for example, by moving the operation to the
|
|
/// start of the entry block. This ensures the preservation of SSA dominance of
|
|
/// the operation's results.
|
|
///
|
|
/// Returns the number of operations sunk.
|
|
size_t
|
|
controlFlowSink(RegionRange regions, DominanceInfo &domInfo,
|
|
function_ref<bool(Operation *, Region *)> shouldMoveIntoRegion,
|
|
function_ref<void(Operation *, Region *)> moveIntoRegion);
|
|
|
|
/// Populates `regions` with regions of the provided region branch op that are
|
|
/// executed at most once at that are reachable given the current operands of
|
|
/// the op. These regions can be passed to `controlFlowSink` to perform sinking
|
|
/// on the regions of the operation.
|
|
void getSinglyExecutedRegionsToSink(RegionBranchOpInterface branch,
|
|
SmallVectorImpl<Region *> ®ions);
|
|
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_TRANSFORMS_CONTROLFLOWSINKUTILS_H
|