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
// ===----------------------------------------------------------------------===//
@@ -786,34 +799,6 @@ void TernaryOp::build(OpBuilder &builder, OperationState &result, Value cond,
786
799
// ===----------------------------------------------------------------------===//
787
800
788
801
mlir::LogicalResult YieldOp::verify () {
789
- auto isDominatedByProperAwaitRegion = [&](Operation *parentOp,
790
- mlir::Region *currRegion) {
791
- while (!llvm::isa<cir::FuncOp>(parentOp)) {
792
- auto awaitOp = dyn_cast<cir::AwaitOp>(parentOp);
793
- if (awaitOp) {
794
- if (currRegion && currRegion == &awaitOp.getResume ()) {
795
- emitOpError () << " kind 'nosuspend' can only be used in 'ready' and "
796
- " 'suspend' regions" ;
797
- return false ;
798
- }
799
- return true ;
800
- }
801
-
802
- currRegion = parentOp->getParentRegion ();
803
- parentOp = parentOp->getParentOp ();
804
- }
805
-
806
- emitOpError () << " shall be dominated by 'cir.await'" ;
807
- return false ;
808
- };
809
-
810
- if (isNoSuspend ()) {
811
- if (!isDominatedByProperAwaitRegion (getOperation ()->getParentOp (),
812
- getOperation ()->getParentRegion ()))
813
- return mlir::failure ();
814
- return mlir::success ();
815
- }
816
-
817
802
if (isFallthrough ()) {
818
803
if (!llvm::isa<SwitchOp>(getOperation ()->getParentOp ()))
819
804
return emitOpError () << " fallthrough only expected within 'cir.switch'" ;
@@ -2223,7 +2208,11 @@ void AwaitOp::getSuccessorRegions(mlir::RegionBranchPoint point,
2223
2208
regions.push_back (RegionSuccessor (&this ->getResume ()));
2224
2209
}
2225
2210
2226
- LogicalResult AwaitOp::verify () { return success (); }
2211
+ LogicalResult AwaitOp::verify () {
2212
+ if (!isa<ConditionOp>(this ->getReady ().back ().getTerminator ()))
2213
+ return emitOpError (" ready region must end with cir.condition" );
2214
+ return success ();
2215
+ }
2227
2216
2228
2217
// ===----------------------------------------------------------------------===//
2229
2218
// CIR defined traits
0 commit comments