1 //===- SCFOps.h - Structured Control Flow -----------------------*- 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 defines structured control flow operations. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef MLIR_DIALECT_SCF_H_ 14 #define MLIR_DIALECT_SCF_H_ 15 16 #include "mlir/IR/Attributes.h" 17 #include "mlir/IR/Builders.h" 18 #include "mlir/IR/Dialect.h" 19 #include "mlir/IR/OpDefinition.h" 20 #include "mlir/Interfaces/ControlFlowInterfaces.h" 21 #include "mlir/Interfaces/LoopLikeInterface.h" 22 #include "mlir/Interfaces/SideEffectInterfaces.h" 23 24 namespace mlir { 25 namespace scf { 26 void buildTerminatedBody(OpBuilder &builder, Location loc); 27 } // namespace scf 28 } // namespace mlir 29 30 #include "mlir/Dialect/SCF/SCFOpsDialect.h.inc" 31 32 #define GET_OP_CLASSES 33 #include "mlir/Dialect/SCF/SCFOps.h.inc" 34 35 namespace mlir { 36 namespace scf { 37 38 // Insert `loop.yield` at the end of the only region's only block if it 39 // does not have a terminator already. If a new `loop.yield` is inserted, 40 // the location is specified by `loc`. If the region is empty, insert a new 41 // block first. 42 void ensureLoopTerminator(Region ®ion, Builder &builder, Location loc); 43 44 /// Returns the loop parent of an induction variable. If the provided value is 45 /// not an induction variable, then return nullptr. 46 ForOp getForInductionVarOwner(Value val); 47 48 /// Returns the parallel loop parent of an induction variable. If the provided 49 /// value is not an induction variable, then return nullptr. 50 ParallelOp getParallelForInductionVarOwner(Value val); 51 52 /// An owning vector of values, handy to return from functions. 53 using ValueVector = std::vector<Value>; 54 using LoopVector = std::vector<scf::ForOp>; 55 struct LoopNest { getResultsLoopNest56 ResultRange getResults() { return loops.front().getResults(); } 57 LoopVector loops; 58 }; 59 60 /// Creates a perfect nest of "for" loops, i.e. all loops but the innermost 61 /// contain only another loop and a terminator. The lower, upper bounds and 62 /// steps are provided as `lbs`, `ubs` and `steps`, which are expected to be of 63 /// the same size. `iterArgs` points to the initial values of the loop iteration 64 /// arguments, which will be forwarded through the nest to the innermost loop. 65 /// The body of the loop is populated using `bodyBuilder`, which accepts an 66 /// ordered list of induction variables of all loops, followed by a list of 67 /// iteration arguments of the innermost loop, in the same order as provided to 68 /// `iterArgs`. This function is expected to return as many values as 69 /// `iterArgs`, of the same type and in the same order, that will be treated as 70 /// yielded from the loop body and forwarded back through the loop nest. If the 71 /// function is not provided, the loop nest is not expected to have iteration 72 /// arguments, the body of the innermost loop will be left empty, containing 73 /// only the zero-operand terminator. Returns the LoopNest containing the list 74 /// of perfectly nest scf::ForOp build during the call. 75 /// If bound arrays are empty, the body builder will be called 76 /// once to construct the IR outside of the loop with an empty list of induction 77 /// variables. 78 LoopNest buildLoopNest( 79 OpBuilder &builder, Location loc, ValueRange lbs, ValueRange ubs, 80 ValueRange steps, ValueRange iterArgs, 81 function_ref<ValueVector(OpBuilder &, Location, ValueRange, ValueRange)> 82 bodyBuilder = nullptr); 83 84 /// A convenience version for building loop nests without iteration arguments 85 /// (like for reductions). Does not take the initial value of reductions or 86 /// expect the body building functions to return their current value. 87 /// The built nested scf::For are captured in `capturedLoops` when non-null. 88 LoopNest buildLoopNest(OpBuilder &builder, Location loc, ValueRange lbs, 89 ValueRange ubs, ValueRange steps, 90 function_ref<void(OpBuilder &, Location, ValueRange)> 91 bodyBuilder = nullptr); 92 93 } // end namespace scf 94 } // end namespace mlir 95 #endif // MLIR_DIALECT_SCF_H_ 96