xref: /freebsd/contrib/llvm-project/clang/include/clang/CIR/Interfaces/CIRLoopOpInterface.td (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric//===---------------------------------------------------------------------===//
2*700637cbSDimitry Andric//
3*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric//
7*700637cbSDimitry Andric//===---------------------------------------------------------------------===//
8*700637cbSDimitry Andric
9*700637cbSDimitry Andric#ifndef CLANG_CIR_INTERFACES_CIRLOOPOPINTERFACE
10*700637cbSDimitry Andric#define CLANG_CIR_INTERFACES_CIRLOOPOPINTERFACE
11*700637cbSDimitry Andric
12*700637cbSDimitry Andricinclude "mlir/IR/OpBase.td"
13*700637cbSDimitry Andricinclude "mlir/Interfaces/ControlFlowInterfaces.td"
14*700637cbSDimitry Andricinclude "mlir/Interfaces/LoopLikeInterface.td"
15*700637cbSDimitry Andric
16*700637cbSDimitry Andricdef LoopOpInterface : OpInterface<"LoopOpInterface", [
17*700637cbSDimitry Andric  DeclareOpInterfaceMethods<RegionBranchOpInterface>,
18*700637cbSDimitry Andric  DeclareOpInterfaceMethods<LoopLikeOpInterface>
19*700637cbSDimitry Andric]> {
20*700637cbSDimitry Andric  let description = [{
21*700637cbSDimitry Andric    Contains helper functions to query properties and perform transformations
22*700637cbSDimitry Andric    on a loop.
23*700637cbSDimitry Andric  }];
24*700637cbSDimitry Andric  let cppNamespace = "::cir";
25*700637cbSDimitry Andric
26*700637cbSDimitry Andric  let methods = [
27*700637cbSDimitry Andric    InterfaceMethod<[{
28*700637cbSDimitry Andric        Returns the loop's conditional region.
29*700637cbSDimitry Andric      }],
30*700637cbSDimitry Andric      /*retTy=*/"mlir::Region &",
31*700637cbSDimitry Andric      /*methodName=*/"getCond"
32*700637cbSDimitry Andric    >,
33*700637cbSDimitry Andric    InterfaceMethod<[{
34*700637cbSDimitry Andric        Returns the loop's body region.
35*700637cbSDimitry Andric      }],
36*700637cbSDimitry Andric      /*retTy=*/"mlir::Region &",
37*700637cbSDimitry Andric      /*methodName=*/"getBody"
38*700637cbSDimitry Andric    >,
39*700637cbSDimitry Andric    InterfaceMethod<[{
40*700637cbSDimitry Andric        Returns a pointer to the loop's step region or nullptr.
41*700637cbSDimitry Andric      }],
42*700637cbSDimitry Andric      /*retTy=*/"mlir::Region *",
43*700637cbSDimitry Andric      /*methodName=*/"maybeGetStep",
44*700637cbSDimitry Andric      /*args=*/(ins),
45*700637cbSDimitry Andric      /*methodBody=*/"",
46*700637cbSDimitry Andric      /*defaultImplementation=*/"return nullptr;"
47*700637cbSDimitry Andric    >,
48*700637cbSDimitry Andric    InterfaceMethod<[{
49*700637cbSDimitry Andric        Returns the first region to be executed in the loop.
50*700637cbSDimitry Andric      }],
51*700637cbSDimitry Andric      /*retTy=*/"mlir::Region &",
52*700637cbSDimitry Andric      /*methodName=*/"getEntry",
53*700637cbSDimitry Andric      /*args=*/(ins),
54*700637cbSDimitry Andric      /*methodBody=*/"",
55*700637cbSDimitry Andric      /*defaultImplementation=*/"return $_op.getCond();"
56*700637cbSDimitry Andric    >,
57*700637cbSDimitry Andric    InterfaceMethod<[{
58*700637cbSDimitry Andric        Returns a list of regions in order of execution.
59*700637cbSDimitry Andric      }],
60*700637cbSDimitry Andric      /*retTy=*/"llvm::SmallVector<mlir::Region *>",
61*700637cbSDimitry Andric      /*methodName=*/"getRegionsInExecutionOrder",
62*700637cbSDimitry Andric      /*args=*/(ins),
63*700637cbSDimitry Andric      /*methodBody=*/"",
64*700637cbSDimitry Andric      /*defaultImplementation=*/[{
65*700637cbSDimitry Andric        return llvm::SmallVector<mlir::Region *, 2>{&$_op.getRegion(0), &$_op.getRegion(1)};
66*700637cbSDimitry Andric      }]
67*700637cbSDimitry Andric    >,
68*700637cbSDimitry Andric    InterfaceMethod<[{
69*700637cbSDimitry Andric        Recursively walks the body of the loop in pre-order while skipping
70*700637cbSDimitry Andric        nested loops and executing a callback on every other operation.
71*700637cbSDimitry Andric      }],
72*700637cbSDimitry Andric      /*retTy=*/"mlir::WalkResult",
73*700637cbSDimitry Andric      /*methodName=*/"walkBodySkippingNestedLoops",
74*700637cbSDimitry Andric      /*args=*/(ins "::llvm::function_ref<mlir::WalkResult (mlir::Operation *)>":$callback),
75*700637cbSDimitry Andric      /*methodBody=*/"",
76*700637cbSDimitry Andric      /*defaultImplementation=*/[{
77*700637cbSDimitry Andric        return $_op.getBody().template walk<mlir::WalkOrder::PreOrder>([&](mlir::Operation *op) {
78*700637cbSDimitry Andric          if (mlir::isa<LoopOpInterface>(op))
79*700637cbSDimitry Andric            return mlir::WalkResult::skip();
80*700637cbSDimitry Andric          return callback(op);
81*700637cbSDimitry Andric        });
82*700637cbSDimitry Andric      }]
83*700637cbSDimitry Andric    >
84*700637cbSDimitry Andric  ];
85*700637cbSDimitry Andric
86*700637cbSDimitry Andric  let extraClassDeclaration = [{
87*700637cbSDimitry Andric    /// Generic method to retrieve the successors of a LoopOpInterface operation.
88*700637cbSDimitry Andric    static void getLoopOpSuccessorRegions(
89*700637cbSDimitry Andric        ::cir::LoopOpInterface op, ::mlir::RegionBranchPoint point,
90*700637cbSDimitry Andric        ::mlir::SmallVectorImpl<::mlir::RegionSuccessor> &regions);
91*700637cbSDimitry Andric  }];
92*700637cbSDimitry Andric
93*700637cbSDimitry Andric  let verify = [{
94*700637cbSDimitry Andric    /// Verify invariants of the LoopOpInterface.
95*700637cbSDimitry Andric    return detail::verifyLoopOpInterface($_op);
96*700637cbSDimitry Andric  }];
97*700637cbSDimitry Andric}
98*700637cbSDimitry Andric
99*700637cbSDimitry Andric#endif // CLANG_CIR_INTERFACES_CIRLOOPOPINTERFACE
100