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 #include "clang/CIR/Interfaces/CIRLoopOpInterface.h" 10*700637cbSDimitry Andric 11*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRDialect.h" 12*700637cbSDimitry Andric #include "clang/CIR/Interfaces/CIRLoopOpInterface.cpp.inc" 13*700637cbSDimitry Andric #include "llvm/Support/ErrorHandling.h" 14*700637cbSDimitry Andric 15*700637cbSDimitry Andric namespace cir { 16*700637cbSDimitry Andric getLoopOpSuccessorRegions(LoopOpInterface op,mlir::RegionBranchPoint point,llvm::SmallVectorImpl<mlir::RegionSuccessor> & regions)17*700637cbSDimitry Andricvoid LoopOpInterface::getLoopOpSuccessorRegions( 18*700637cbSDimitry Andric LoopOpInterface op, mlir::RegionBranchPoint point, 19*700637cbSDimitry Andric llvm::SmallVectorImpl<mlir::RegionSuccessor> ®ions) { 20*700637cbSDimitry Andric assert(point.isParent() || point.getRegionOrNull()); 21*700637cbSDimitry Andric 22*700637cbSDimitry Andric // Branching to first region: go to condition or body (do-while). 23*700637cbSDimitry Andric if (point.isParent()) { 24*700637cbSDimitry Andric regions.emplace_back(&op.getEntry(), op.getEntry().getArguments()); 25*700637cbSDimitry Andric return; 26*700637cbSDimitry Andric } 27*700637cbSDimitry Andric 28*700637cbSDimitry Andric // Branching from condition: go to body or exit. 29*700637cbSDimitry Andric if (&op.getCond() == point.getRegionOrNull()) { 30*700637cbSDimitry Andric regions.emplace_back(mlir::RegionSuccessor(op->getResults())); 31*700637cbSDimitry Andric regions.emplace_back(&op.getBody(), op.getBody().getArguments()); 32*700637cbSDimitry Andric return; 33*700637cbSDimitry Andric } 34*700637cbSDimitry Andric 35*700637cbSDimitry Andric // Branching from body: go to step (for) or condition. 36*700637cbSDimitry Andric if (&op.getBody() == point.getRegionOrNull()) { 37*700637cbSDimitry Andric // FIXME(cir): Should we consider break/continue statements here? 38*700637cbSDimitry Andric mlir::Region *afterBody = 39*700637cbSDimitry Andric (op.maybeGetStep() ? op.maybeGetStep() : &op.getCond()); 40*700637cbSDimitry Andric regions.emplace_back(afterBody, afterBody->getArguments()); 41*700637cbSDimitry Andric return; 42*700637cbSDimitry Andric } 43*700637cbSDimitry Andric 44*700637cbSDimitry Andric // Branching from step: go to condition. 45*700637cbSDimitry Andric if (op.maybeGetStep() == point.getRegionOrNull()) { 46*700637cbSDimitry Andric regions.emplace_back(&op.getCond(), op.getCond().getArguments()); 47*700637cbSDimitry Andric return; 48*700637cbSDimitry Andric } 49*700637cbSDimitry Andric 50*700637cbSDimitry Andric llvm_unreachable("unexpected branch origin"); 51*700637cbSDimitry Andric } 52*700637cbSDimitry Andric 53*700637cbSDimitry Andric /// Verify invariants of the LoopOpInterface. verifyLoopOpInterface(mlir::Operation * op)54*700637cbSDimitry Andricllvm::LogicalResult detail::verifyLoopOpInterface(mlir::Operation *op) { 55*700637cbSDimitry Andric // FIXME: fix this so the conditionop isn't requiring MLIRCIR 56*700637cbSDimitry Andric // auto loopOp = mlir::cast<LoopOpInterface>(op); 57*700637cbSDimitry Andric // if (!mlir::isa<ConditionOp>(loopOp.getCond().back().getTerminator())) 58*700637cbSDimitry Andric // return op->emitOpError( 59*700637cbSDimitry Andric // "expected condition region to terminate with 'cir.condition'"); 60*700637cbSDimitry Andric return llvm::success(); 61*700637cbSDimitry Andric } 62*700637cbSDimitry Andric 63*700637cbSDimitry Andric } // namespace cir 64