MLIR  19.0.0git
IRDLTraits.h
Go to the documentation of this file.
1 //===- IRDLTraits.h - IRDL traits definition ---------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the traits used by the IR Definition Language dialect.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
15 #define MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
16 
17 #include "mlir/IR/OpDefinition.h"
19 #include "llvm/Support/Casting.h"
20 
21 namespace mlir {
22 namespace OpTrait {
23 
24 /// Characterize operations that have at most a single operation of certain
25 /// types in their region.
26 /// This check is only done on the children that are immediate children of the
27 /// operation, and does not recurse into the children's regions.
28 /// This trait expects the Op to satisfy the `OneRegion` trait.
29 template <typename... ChildOps>
31 public:
32  template <typename ConcreteType>
33  class Impl
34  : public TraitBase<ConcreteType, AtMostOneChildOf<ChildOps...>::Impl> {
35  public:
37  static_assert(
38  ConcreteType::template hasTrait<::mlir::OpTrait::OneRegion>(),
39  "expected operation to have a single region");
40  static_assert(sizeof...(ChildOps) > 0,
41  "expected at least one child operation type");
42 
43  // Contains `true` if the corresponding child op has been seen.
44  bool satisfiedOps[sizeof...(ChildOps)] = {};
45 
46  for (Operation &child : cast<ConcreteType>(op).getOps()) {
47  int childOpIndex = 0;
48  if (((isa<ChildOps>(child) ? false : (++childOpIndex, true)) && ...))
49  continue;
50 
51  // Check that the operation has not been seen before.
52  if (satisfiedOps[childOpIndex])
53  return op->emitError()
54  << "failed to verify AtMostOneChildOf trait: the operation "
55  "contains at least two operations of type "
56  << child.getName();
57 
58  // Mark the operation as seen.
59  satisfiedOps[childOpIndex] = true;
60  }
61  return success();
62  }
63 
64  /// Get the unique operation of a specific op that is in the operation
65  /// region.
66  template <typename OpT>
67  std::enable_if_t<std::disjunction<std::is_same<OpT, ChildOps>...>::value,
68  std::optional<OpT>>
69  getOp() {
70  auto ops =
71  cast<ConcreteType>(this->getOperation()).template getOps<OpT>();
72  if (ops.empty())
73  return {};
74  return {*ops.begin()};
75  }
76  };
77 };
78 } // namespace OpTrait
79 } // namespace mlir
80 
81 #endif // MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
static LogicalResult verifyTrait(Operation *op)
Definition: IRDLTraits.h:36
std::enable_if_t< std::disjunction< std::is_same< OpT, ChildOps >... >::value, std::optional< OpT > > getOp()
Get the unique operation of a specific op that is in the operation region.
Definition: IRDLTraits.h:69
Characterize operations that have at most a single operation of certain types in their region.
Definition: IRDLTraits.h:30
Helper class for implementing traits.
Definition: OpDefinition.h:373
Operation * getOperation()
Return the ultimate Operation being worked on.
Definition: OpDefinition.h:376
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Include the generated interface declarations.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26