81 lines
3.6 KiB
C++
81 lines
3.6 KiB
C++
//===- ControlFlowToSCF.h - ControlFlow to SCF -------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Define conversions from the ControlFlow dialect to the SCF dialect.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
|
|
#define MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
|
|
|
|
#include <memory>
|
|
|
|
#include "mlir/Transforms/CFGToSCF.h"
|
|
|
|
namespace mlir {
|
|
class Pass;
|
|
|
|
/// Implementation of `CFGToSCFInterface` used to lift Control Flow Dialect
|
|
/// operations to SCF Dialect operations.
|
|
class ControlFlowToSCFTransformation : public CFGToSCFInterface {
|
|
public:
|
|
/// Returns true only for `cf.cond_br` and `cf.switch`, the two multi-
|
|
/// successor ops this transformation knows how to convert.
|
|
bool canConvertMultiSuccessorBranchOp(Operation *op) override;
|
|
|
|
/// Creates an `scf.if` op if `controlFlowCondOp` is a `cf.cond_br` op or
|
|
/// an `scf.index_switch` if `controlFlowCondOp` is a `cf.switch`.
|
|
/// Returns failure otherwise.
|
|
FailureOr<Operation *> createStructuredBranchRegionOp(
|
|
OpBuilder &builder, Operation *controlFlowCondOp, TypeRange resultTypes,
|
|
MutableArrayRef<Region> regions) override;
|
|
|
|
/// Creates an `scf.yield` op returning the given results.
|
|
LogicalResult createStructuredBranchRegionTerminatorOp(
|
|
Location loc, OpBuilder &builder, Operation *branchRegionOp,
|
|
Operation *replacedControlFlowOp, ValueRange results) override;
|
|
|
|
/// Creates an `scf.while` op. The loop body is made the before-region of the
|
|
/// while op and terminated with an `scf.condition` op. The after-region does
|
|
/// nothing but forward the iteration variables.
|
|
FailureOr<Operation *>
|
|
createStructuredDoWhileLoopOp(OpBuilder &builder, Operation *replacedOp,
|
|
ValueRange loopVariablesInit, Value condition,
|
|
ValueRange loopVariablesNextIter,
|
|
Region &&loopBody) override;
|
|
|
|
/// Creates an `arith.constant` with an i32 attribute of the given value.
|
|
Value getCFGSwitchValue(Location loc, OpBuilder &builder,
|
|
unsigned value) override;
|
|
|
|
/// Creates a `cf.switch` op with the given cases and flag.
|
|
void createCFGSwitchOp(Location loc, OpBuilder &builder, Value flag,
|
|
ArrayRef<unsigned> caseValues,
|
|
BlockRange caseDestinations,
|
|
ArrayRef<ValueRange> caseArguments, Block *defaultDest,
|
|
ValueRange defaultArgs) override;
|
|
|
|
/// Creates a `ub.poison` op of the given type.
|
|
Value getUndefValue(Location loc, OpBuilder &builder, Type type) override;
|
|
|
|
/// Creates a `func.return` op with poison for each of the return values of
|
|
/// the function. It is guaranteed to be directly within the function body.
|
|
/// TODO: This can be made independent of the `func` dialect once the UB
|
|
/// dialect has a `ub.unreachable` op.
|
|
FailureOr<Operation *> createUnreachableTerminator(Location loc,
|
|
OpBuilder &builder,
|
|
Region ®ion) override;
|
|
};
|
|
|
|
#define GEN_PASS_DECL_LIFTCONTROLFLOWTOSCFPASS
|
|
#include "mlir/Conversion/Passes.h.inc"
|
|
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
|