xref: /llvm-project/mlir/include/mlir/Conversion/ControlFlowToSCF/ControlFlowToSCF.h (revision 359ba0b00806c6fba325733e817637522b8c6e19)
1 //===- ControlFlowToSCF.h - ControlFlow to SCF -------------*- 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 // Define conversions from the ControlFlow dialect to the SCF dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
14 #define MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
15 
16 #include <memory>
17 
18 #include "mlir/Transforms/CFGToSCF.h"
19 
20 namespace mlir {
21 class Pass;
22 
23 /// Implementation of `CFGToSCFInterface` used to lift Control Flow Dialect
24 /// operations to SCF Dialect operations.
25 class ControlFlowToSCFTransformation : public CFGToSCFInterface {
26 public:
27   /// Creates an `scf.if` op if `controlFlowCondOp` is a `cf.cond_br` op or
28   /// an `scf.index_switch` if `controlFlowCondOp` is a `cf.switch`.
29   /// Returns failure otherwise.
30   FailureOr<Operation *> createStructuredBranchRegionOp(
31       OpBuilder &builder, Operation *controlFlowCondOp, TypeRange resultTypes,
32       MutableArrayRef<Region> regions) override;
33 
34   /// Creates an `scf.yield` op returning the given results.
35   LogicalResult createStructuredBranchRegionTerminatorOp(
36       Location loc, OpBuilder &builder, Operation *branchRegionOp,
37       Operation *replacedControlFlowOp, ValueRange results) override;
38 
39   /// Creates an `scf.while` op. The loop body is made the before-region of the
40   /// while op and terminated with an `scf.condition` op. The after-region does
41   /// nothing but forward the iteration variables.
42   FailureOr<Operation *>
43   createStructuredDoWhileLoopOp(OpBuilder &builder, Operation *replacedOp,
44                                 ValueRange loopVariablesInit, Value condition,
45                                 ValueRange loopVariablesNextIter,
46                                 Region &&loopBody) override;
47 
48   /// Creates an `arith.constant` with an i32 attribute of the given value.
49   Value getCFGSwitchValue(Location loc, OpBuilder &builder,
50                           unsigned value) override;
51 
52   /// Creates a `cf.switch` op with the given cases and flag.
53   void createCFGSwitchOp(Location loc, OpBuilder &builder, Value flag,
54                          ArrayRef<unsigned> caseValues,
55                          BlockRange caseDestinations,
56                          ArrayRef<ValueRange> caseArguments, Block *defaultDest,
57                          ValueRange defaultArgs) override;
58 
59   /// Creates a `ub.poison` op of the given type.
60   Value getUndefValue(Location loc, OpBuilder &builder, Type type) override;
61 
62   /// Creates a `func.return` op with poison for each of the return values of
63   /// the function. It is guaranteed to be directly within the function body.
64   /// TODO: This can be made independent of the `func` dialect once the UB
65   ///       dialect has a `ub.unreachable` op.
66   FailureOr<Operation *> createUnreachableTerminator(Location loc,
67                                                      OpBuilder &builder,
68                                                      Region &region) override;
69 };
70 
71 #define GEN_PASS_DECL_LIFTCONTROLFLOWTOSCFPASS
72 #include "mlir/Conversion/Passes.h.inc"
73 
74 } // namespace mlir
75 
76 #endif // MLIR_CONVERSION_CONTROLFLOWTOSCF_CONTROLFLOWTOSCF_H
77