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