clang 24.0.0git
CIRLoopOpInterface.cpp
Go to the documentation of this file.
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
10
12#include "clang/CIR/Interfaces/CIRLoopOpInterface.cpp.inc"
13#include "llvm/Support/ErrorHandling.h"
14
15namespace cir {
16
17void LoopOpInterface::getLoopOpSuccessorRegions(
18 LoopOpInterface op, mlir::RegionBranchPoint point,
19 llvm::SmallVectorImpl<mlir::RegionSuccessor> &regions) {
20 assert(point.isParent() || point.getTerminatorPredecessorOrNull());
21
22 // Branching to first region: go to condition or body (do-while).
23 if (point.isParent()) {
24 regions.emplace_back(&op.getEntry());
25 return;
26 }
27
28 mlir::Region *parentRegion =
29 point.getTerminatorPredecessorOrNull()->getParentRegion();
30
31 mlir::Region *step = op.maybeGetStep();
32 mlir::Region *cleanup = op.maybeGetCleanup();
33
34 // Branching from condition: go to body, or (on the false edge) route
35 // through the cleanup region if present, otherwise exit the loop.
36 if (&op.getCond() == parentRegion) {
37 if (cleanup)
38 regions.emplace_back(cleanup);
39 else
40 regions.emplace_back(op);
41 regions.emplace_back(&op.getBody());
42 return;
43 }
44
45 // Branching from body: go to step (for), otherwise route through the
46 // cleanup region if present, otherwise go back to the condition.
47 if (&op.getBody() == parentRegion) {
48 // FIXME(cir): Should we consider break/continue statements here?
49 if (step)
50 regions.emplace_back(step);
51 else if (cleanup)
52 regions.emplace_back(cleanup);
53 else
54 regions.emplace_back(&op.getCond());
55 return;
56 }
57
58 // Branching from step: route through the cleanup region if present,
59 // otherwise go back to the condition.
60 if (step == parentRegion) {
61 if (cleanup)
62 regions.emplace_back(cleanup);
63 else
64 regions.emplace_back(&op.getCond());
65 return;
66 }
67
68 // Branching from cleanup: either loop back to the condition (normal
69 // end-of-iteration) or exit the loop (condition-false edge).
70 if (cleanup == parentRegion) {
71 regions.emplace_back(&op.getCond());
72 regions.emplace_back(op);
73 return;
74 }
75
76 llvm_unreachable("unexpected branch origin");
77}
78
79mlir::ValueRange
80LoopOpInterface::getLoopOpSuccessorInputs(LoopOpInterface op,
81 mlir::RegionSuccessor successor) {
82 if (successor.isOperation())
83 return op->getResults();
84 if (mlir::Region *region = successor.getSuccessor())
85 return region->getArguments();
86 llvm_unreachable("invalid region successor");
87}
88
89/// Verify invariants of the LoopOpInterface.
90llvm::LogicalResult detail::verifyLoopOpInterface(mlir::Operation *op) {
91 // FIXME: fix this so the conditionop isn't requiring MLIRCIR
92 // auto loopOp = mlir::cast<LoopOpInterface>(op);
93 // if (!mlir::isa<ConditionOp>(loopOp.getCond().back().getTerminator()))
94 // return op->emitOpError(
95 // "expected condition region to terminate with 'cir.condition'");
96 return llvm::success();
97}
98
99} // namespace cir
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="<stdin>")
Clean up any erroneous/redundant code in the given Ranges in Code.
mlir::LogicalResult verifyLoopOpInterface(::mlir::Operation *op)
Verify invariants of the LoopOpInterface.
float __ovld __cnfn step(float, float)
Returns 0.0 if x < edge, otherwise it returns 1.0.