xref: /freebsd/contrib/llvm-project/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp (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 #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 Andric void LoopOpInterface::getLoopOpSuccessorRegions(
18*700637cbSDimitry Andric     LoopOpInterface op, mlir::RegionBranchPoint point,
19*700637cbSDimitry Andric     llvm::SmallVectorImpl<mlir::RegionSuccessor> &regions) {
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 Andric llvm::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