• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ControlFlowInterfaces.h - ControlFlow Interfaces ---------*- 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 // This file contains the definitions of the branch interfaces defined in
10 // `ControlFlowInterfaces.td`.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_INTERFACES_CONTROLFLOWINTERFACES_H
15 #define MLIR_INTERFACES_CONTROLFLOWINTERFACES_H
16 
17 #include "mlir/IR/OpDefinition.h"
18 
19 namespace mlir {
20 class BranchOpInterface;
21 class RegionBranchOpInterface;
22 
23 //===----------------------------------------------------------------------===//
24 // BranchOpInterface
25 //===----------------------------------------------------------------------===//
26 
27 namespace detail {
28 /// Return the `BlockArgument` corresponding to operand `operandIndex` in some
29 /// successor if `operandIndex` is within the range of `operands`, or None if
30 /// `operandIndex` isn't a successor operand index.
31 Optional<BlockArgument>
32 getBranchSuccessorArgument(Optional<OperandRange> operands,
33                            unsigned operandIndex, Block *successor);
34 
35 /// Verify that the given operands match those of the given successor block.
36 LogicalResult verifyBranchSuccessorOperands(Operation *op, unsigned succNo,
37                                             Optional<OperandRange> operands);
38 } // namespace detail
39 
40 //===----------------------------------------------------------------------===//
41 // RegionBranchOpInterface
42 //===----------------------------------------------------------------------===//
43 
44 // A constant value to represent unknown number of region invocations.
45 extern const int64_t kUnknownNumRegionInvocations;
46 
47 namespace detail {
48 /// Verify that types match along control flow edges described the given op.
49 LogicalResult verifyTypesAlongControlFlowEdges(Operation *op);
50 } //  namespace detail
51 
52 /// This class represents a successor of a region. A region successor can either
53 /// be another region, or the parent operation. If the successor is a region,
54 /// this class represents the destination region, as well as a set of arguments
55 /// from that region that will be populated by values from the current region.
56 /// If the successor is the parent operation, this class represents an optional
57 /// set of results that will be populated by values from the current region.
58 ///
59 /// This interface assumes that the values from the current region that are used
60 /// to populate the successor inputs are the operands of the return-like
61 /// terminator operations in the blocks within this region.
62 class RegionSuccessor {
63 public:
64   /// Initialize a successor that branches to another region of the parent
65   /// operation.
66   RegionSuccessor(Region *region, Block::BlockArgListType regionInputs = {})
region(region)67       : region(region), inputs(regionInputs) {}
68   /// Initialize a successor that branches back to/out of the parent operation.
69   RegionSuccessor(Optional<Operation::result_range> results = {})
region(nullptr)70       : region(nullptr), inputs(results ? ValueRange(*results) : ValueRange()) {
71   }
72 
73   /// Return the given region successor. Returns nullptr if the successor is the
74   /// parent operation.
getSuccessor()75   Region *getSuccessor() const { return region; }
76 
77   /// Return true if the successor is the parent operation.
isParent()78   bool isParent() const { return region == nullptr; }
79 
80   /// Return the inputs to the successor that are remapped by the exit values of
81   /// the current region.
getSuccessorInputs()82   ValueRange getSuccessorInputs() const { return inputs; }
83 
84 private:
85   Region *region;
86   ValueRange inputs;
87 };
88 
89 //===----------------------------------------------------------------------===//
90 // ControlFlow Traits
91 //===----------------------------------------------------------------------===//
92 
93 namespace OpTrait {
94 /// This trait indicates that a terminator operation is "return-like". This
95 /// means that it exits its current region and forwards its operands as "exit"
96 /// values to the parent region. Operations with this trait are not permitted to
97 /// contain successors or produce results.
98 template <typename ConcreteType>
99 struct ReturnLike : public TraitBase<ConcreteType, ReturnLike> {
verifyTraitReturnLike100   static LogicalResult verifyTrait(Operation *op) {
101     static_assert(ConcreteType::template hasTrait<IsTerminator>(),
102                   "expected operation to be a terminator");
103     static_assert(ConcreteType::template hasTrait<ZeroResult>(),
104                   "expected operation to have zero results");
105     static_assert(ConcreteType::template hasTrait<ZeroSuccessor>(),
106                   "expected operation to have zero successors");
107     return success();
108   }
109 };
110 } // namespace OpTrait
111 
112 } // end namespace mlir
113 
114 //===----------------------------------------------------------------------===//
115 // ControlFlow Interfaces
116 //===----------------------------------------------------------------------===//
117 
118 /// Include the generated interface declarations.
119 #include "mlir/Interfaces/ControlFlowInterfaces.h.inc"
120 
121 #endif // MLIR_INTERFACES_CONTROLFLOWINTERFACES_H
122