14
14
#include " clang/CIR/Dialect/IR/CIRAttrs.h"
15
15
#include " clang/CIR/Dialect/IR/CIROpsEnums.h"
16
16
#include " clang/CIR/Dialect/IR/CIRTypes.h"
17
+ #include " llvm/Support/ErrorHandling.h"
17
18
#include < optional>
18
19
19
20
#include " mlir/Dialect/Func/IR/FuncOps.h"
@@ -246,13 +247,19 @@ LogicalResult BreakOp::verify() {
246
247
247
248
void ConditionOp::getSuccessorRegions (
248
249
ArrayRef<Attribute> operands, SmallVectorImpl<RegionSuccessor> ®ions) {
249
- auto loopOp = cast<LoopOp>(getOperation ()->getParentOp ());
250
-
251
250
// TODO(cir): The condition value may be folded to a constant, narrowing
252
251
// down its list of possible successors.
253
- // Condition may branch to the body or to the parent op.
254
- regions.emplace_back (&loopOp.getBody (), loopOp.getBody ().getArguments ());
255
- regions.emplace_back (loopOp->getResults ());
252
+
253
+ // Parent is a loop: condition may branch to the body or to the parent op.
254
+ if (auto loopOp = dyn_cast<LoopOp>(getOperation ()->getParentOp ())) {
255
+ regions.emplace_back (&loopOp.getBody (), loopOp.getBody ().getArguments ());
256
+ regions.emplace_back (loopOp->getResults ());
257
+ }
258
+
259
+ // Parent is an await: condition may branch to resume or suspend regions.
260
+ auto await = cast<AwaitOp>(getOperation ()->getParentOp ());
261
+ regions.emplace_back (&await.getResume (), await.getResume ().getArguments ());
262
+ regions.emplace_back (&await.getSuspend (), await.getSuspend ().getArguments ());
256
263
}
257
264
258
265
MutableOperandRange
@@ -261,6 +268,12 @@ ConditionOp::getMutableSuccessorOperands(RegionBranchPoint point) {
261
268
return MutableOperandRange (getOperation (), 0 , 0 );
262
269
}
263
270
271
+ LogicalResult ConditionOp::verify () {
272
+ if (!isa<LoopOp, AwaitOp>(getOperation ()->getParentOp ()))
273
+ return emitOpError (" condition must be within a conditional region" );
274
+ return success ();
275
+ }
276
+
264
277
// ===----------------------------------------------------------------------===//
265
278
// ConstantOp
266
279
// ===----------------------------------------------------------------------===//
@@ -791,34 +804,6 @@ void TernaryOp::build(OpBuilder &builder, OperationState &result, Value cond,
791
804
// ===----------------------------------------------------------------------===//
792
805
793
806
mlir::LogicalResult YieldOp::verify () {
794
- auto isDominatedByProperAwaitRegion = [&](Operation *parentOp,
795
- mlir::Region *currRegion) {
796
- while (!llvm::isa<cir::FuncOp>(parentOp)) {
797
- auto awaitOp = dyn_cast<cir::AwaitOp>(parentOp);
798
- if (awaitOp) {
799
- if (currRegion && currRegion == &awaitOp.getResume ()) {
800
- emitOpError () << " kind 'nosuspend' can only be used in 'ready' and "
801
- " 'suspend' regions" ;
802
- return false ;
803
- }
804
- return true ;
805
- }
806
-
807
- currRegion = parentOp->getParentRegion ();
808
- parentOp = parentOp->getParentOp ();
809
- }
810
-
811
- emitOpError () << " shall be dominated by 'cir.await'" ;
812
- return false ;
813
- };
814
-
815
- if (isNoSuspend ()) {
816
- if (!isDominatedByProperAwaitRegion (getOperation ()->getParentOp (),
817
- getOperation ()->getParentRegion ()))
818
- return mlir::failure ();
819
- return mlir::success ();
820
- }
821
-
822
807
if (isFallthrough ()) {
823
808
if (!llvm::isa<SwitchOp>(getOperation ()->getParentOp ()))
824
809
return emitOpError () << " fallthrough only expected within 'cir.switch'" ;
@@ -2242,7 +2227,11 @@ void AwaitOp::getSuccessorRegions(mlir::RegionBranchPoint point,
2242
2227
regions.push_back (RegionSuccessor (&this ->getResume ()));
2243
2228
}
2244
2229
2245
- LogicalResult AwaitOp::verify () { return success (); }
2230
+ LogicalResult AwaitOp::verify () {
2231
+ if (!isa<ConditionOp>(this ->getReady ().back ().getTerminator ()))
2232
+ return emitOpError (" ready region must end with cir.condition" );
2233
+ return success ();
2234
+ }
2246
2235
2247
2236
// ===----------------------------------------------------------------------===//
2248
2237
// CIR defined traits
0 commit comments