@@ -3101,17 +3101,32 @@ void CancelOp::build(OpBuilder &builder, OperationState &state,
3101
3101
CancelOp::build (builder, state, clauses.cancelDirective , clauses.ifExpr );
3102
3102
}
3103
3103
3104
+ static Operation *getParentInSameDialect (Operation *thisOp) {
3105
+ mlir::Operation *parent = thisOp->getParentOp ();
3106
+ while (parent) {
3107
+ if (parent->getDialect () == thisOp->getDialect ())
3108
+ return parent;
3109
+ parent = parent->getParentOp ();
3110
+ }
3111
+ return nullptr ;
3112
+ }
3113
+
3104
3114
LogicalResult CancelOp::verify () {
3105
3115
ClauseCancellationConstructType cct = getCancelDirective ();
3106
- Operation *thisOp = (*this ).getOperation ();
3116
+ // The next OpenMP operation in the chain of parents
3117
+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3118
+ if (!structuralParent)
3119
+ return emitOpError () << " Orphaned cancel construct" ;
3107
3120
3108
3121
if ((cct == ClauseCancellationConstructType::Parallel) &&
3109
- !thisOp-> getParentOfType <ParallelOp>()) {
3122
+ !mlir::isa <ParallelOp>(structuralParent )) {
3110
3123
return emitOpError () << " cancel parallel must appear "
3111
3124
<< " inside a parallel region" ;
3112
3125
}
3113
3126
if (cct == ClauseCancellationConstructType::Loop) {
3114
- auto wsloopOp = thisOp->getParentOfType <WsloopOp>();
3127
+ // structural parent will be omp.loop_nest, directly nested inside
3128
+ // omp.wsloop
3129
+ auto wsloopOp = mlir::dyn_cast<WsloopOp>(structuralParent->getParentOp ());
3115
3130
3116
3131
if (!wsloopOp) {
3117
3132
return emitOpError ()
@@ -3127,7 +3142,10 @@ LogicalResult CancelOp::verify() {
3127
3142
}
3128
3143
3129
3144
} else if (cct == ClauseCancellationConstructType::Sections) {
3130
- auto sectionsOp = thisOp->getParentOfType <SectionsOp>();
3145
+ // structural parent will be an omp.section, directly nested inside
3146
+ // omp.sections
3147
+ auto sectionsOp =
3148
+ mlir::dyn_cast<SectionsOp>(structuralParent->getParentOp ());
3131
3149
if (!sectionsOp) {
3132
3150
return emitOpError () << " cancel sections must appear "
3133
3151
<< " inside a sections region" ;
@@ -3152,20 +3170,25 @@ void CancellationPointOp::build(OpBuilder &builder, OperationState &state,
3152
3170
3153
3171
LogicalResult CancellationPointOp::verify () {
3154
3172
ClauseCancellationConstructType cct = getCancelDirective ();
3155
- Operation *thisOp = (*this ).getOperation ();
3173
+ // The next OpenMP operation in the chain of parents
3174
+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3175
+ if (!structuralParent)
3176
+ return emitOpError () << " Orphaned cancellation point" ;
3156
3177
3157
3178
if ((cct == ClauseCancellationConstructType::Parallel) &&
3158
- !thisOp-> getParentOfType <ParallelOp>()) {
3179
+ !mlir::isa <ParallelOp>(structuralParent )) {
3159
3180
return emitOpError () << " cancellation point parallel must appear "
3160
3181
<< " inside a parallel region" ;
3161
3182
}
3183
+ // Strucutal parent here will be an omp.loop_nest. Get the parent of that to
3184
+ // find the wsloop
3162
3185
if ((cct == ClauseCancellationConstructType::Loop) &&
3163
- !thisOp-> getParentOfType <WsloopOp>()) {
3186
+ !mlir::isa <WsloopOp>(structuralParent-> getParentOp () )) {
3164
3187
return emitOpError () << " cancellation point loop must appear "
3165
3188
<< " inside a worksharing-loop region" ;
3166
3189
}
3167
3190
if ((cct == ClauseCancellationConstructType::Sections) &&
3168
- !thisOp-> getParentOfType <SectionsOp>( )) {
3191
+ !mlir::isa<omp::SectionOp>(structuralParent )) {
3169
3192
return emitOpError () << " cancellation point sections must appear "
3170
3193
<< " inside a sections region" ;
3171
3194
}
0 commit comments