@@ -3162,24 +3162,32 @@ void CancelOp::build(OpBuilder &builder, OperationState &state,
3162
3162
CancelOp::build (builder, state, clauses.cancelDirective , clauses.ifExpr );
3163
3163
}
3164
3164
3165
+ static Operation *getParentInSameDialect (Operation *thisOp) {
3166
+ Operation *parent = thisOp->getParentOp ();
3167
+ while (parent) {
3168
+ if (parent->getDialect () == thisOp->getDialect ())
3169
+ return parent;
3170
+ parent = parent->getParentOp ();
3171
+ }
3172
+ return nullptr ;
3173
+ }
3174
+
3165
3175
LogicalResult CancelOp::verify () {
3166
3176
ClauseCancellationConstructType cct = getCancelDirective ();
3167
- Operation *parentOp = (*this )->getParentOp ();
3168
-
3169
- if (!parentOp) {
3170
- return emitOpError () << " must be used within a region supporting "
3171
- " cancel directive" ;
3172
- }
3177
+ // The next OpenMP operation in the chain of parents
3178
+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3179
+ if (!structuralParent)
3180
+ return emitOpError () << " Orphaned cancel construct" ;
3173
3181
3174
3182
if ((cct == ClauseCancellationConstructType::Parallel) &&
3175
- !isa<ParallelOp>(parentOp )) {
3183
+ !mlir:: isa<ParallelOp>(structuralParent )) {
3176
3184
return emitOpError () << " cancel parallel must appear "
3177
3185
<< " inside a parallel region" ;
3178
3186
}
3179
3187
if (cct == ClauseCancellationConstructType::Loop) {
3180
- auto loopOp = dyn_cast<LoopNestOp>(parentOp);
3181
- auto wsloopOp = llvm::dyn_cast_if_present<WsloopOp>(
3182
- loopOp ? loopOp ->getParentOp () : nullptr );
3188
+ // structural parent will be omp.loop_nest, directly nested inside
3189
+ // omp.wsloop
3190
+ auto wsloopOp = mlir::dyn_cast<WsloopOp>(structuralParent ->getParentOp ());
3183
3191
3184
3192
if (!wsloopOp) {
3185
3193
return emitOpError ()
@@ -3195,12 +3203,15 @@ LogicalResult CancelOp::verify() {
3195
3203
}
3196
3204
3197
3205
} else if (cct == ClauseCancellationConstructType::Sections) {
3198
- if (!(isa<SectionsOp>(parentOp) || isa<SectionOp>(parentOp))) {
3206
+ // structural parent will be an omp.section, directly nested inside
3207
+ // omp.sections
3208
+ auto sectionsOp =
3209
+ mlir::dyn_cast<SectionsOp>(structuralParent->getParentOp ());
3210
+ if (!sectionsOp) {
3199
3211
return emitOpError () << " cancel sections must appear "
3200
3212
<< " inside a sections region" ;
3201
3213
}
3202
- if (isa_and_nonnull<SectionsOp>(parentOp->getParentOp ()) &&
3203
- cast<SectionsOp>(parentOp->getParentOp ()).getNowaitAttr ()) {
3214
+ if (sectionsOp.getNowait ()) {
3204
3215
return emitError () << " A sections construct that is canceled "
3205
3216
<< " must not have a nowait clause" ;
3206
3217
}
@@ -3220,25 +3231,25 @@ void CancellationPointOp::build(OpBuilder &builder, OperationState &state,
3220
3231
3221
3232
LogicalResult CancellationPointOp::verify () {
3222
3233
ClauseCancellationConstructType cct = getCancelDirective ();
3223
- Operation *parentOp = (*this )->getParentOp ();
3224
-
3225
- if (!parentOp) {
3226
- return emitOpError () << " must be used within a region supporting "
3227
- " cancellation point directive" ;
3228
- }
3234
+ // The next OpenMP operation in the chain of parents
3235
+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3236
+ if (!structuralParent)
3237
+ return emitOpError () << " Orphaned cancellation point" ;
3229
3238
3230
3239
if ((cct == ClauseCancellationConstructType::Parallel) &&
3231
- !( isa<ParallelOp>(parentOp) )) {
3240
+ !mlir:: isa<ParallelOp>(structuralParent )) {
3232
3241
return emitOpError () << " cancellation point parallel must appear "
3233
3242
<< " inside a parallel region" ;
3234
3243
}
3244
+ // Strucutal parent here will be an omp.loop_nest. Get the parent of that to
3245
+ // find the wsloop
3235
3246
if ((cct == ClauseCancellationConstructType::Loop) &&
3236
- (! isa<LoopNestOp>(parentOp) || !isa< WsloopOp>(parentOp ->getParentOp () ))) {
3247
+ !mlir:: isa<WsloopOp>(structuralParent ->getParentOp ())) {
3237
3248
return emitOpError () << " cancellation point loop must appear "
3238
3249
<< " inside a worksharing-loop region" ;
3239
3250
}
3240
3251
if ((cct == ClauseCancellationConstructType::Sections) &&
3241
- !( isa<SectionsOp>(parentOp) || isa< SectionOp>(parentOp) )) {
3252
+ !mlir:: isa<omp:: SectionOp>(structuralParent )) {
3242
3253
return emitOpError () << " cancellation point sections must appear "
3243
3254
<< " inside a sections region" ;
3244
3255
}
0 commit comments