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> ®ions); 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