@@ -780,19 +780,38 @@ bool ClauseProcessor::processTargetDepend(
780
780
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
781
781
782
782
// Create the new omp.task op.
783
- // As per the OpenMP Spec a target directive creates a mergeable 'target
784
- // task'
783
+ // Whether we create a mergeable task or not depends upon the presence of the
784
+ // nowait clause on the target construct.
785
+ // If the nowait clause is not present on the target construct, then as per
786
+ // the spec, the target task is an included task. We add if(0) clause to the
787
+ // task that we create. A task with an if clause that evaluates to false is
788
+ // undeferred and because this value is known at compile time, it is an
789
+ // included task. And an included task is also mergeable. So, we don't bother
790
+ // with the mergeable clause here. If the nowait clause is present on the
791
+ // target construct, then as per the spec, the execution of the target task
792
+ // may be deferred. This makes it trivially not mergeable.
793
+ mlir::omp::NowaitClauseOps nowaitClauseOp;
794
+ markClauseOccurrence<omp::clause::Nowait>(nowaitClauseOp.nowaitAttr );
795
+
785
796
mlir::omp::TaskOp taskOp = firOpBuilder.create <mlir::omp::TaskOp>(
786
- currentLocation, /* if_expr*/ mlir::Value (),
797
+ currentLocation,
798
+ /* if_expr*/ nowaitClauseOp.nowaitAttr
799
+ ? firOpBuilder.createBool (currentLocation, true )
800
+ : firOpBuilder.createBool (currentLocation, false ),
787
801
/* final_expr*/ mlir::Value (), /* untied*/ mlir::UnitAttr (),
788
- /* mergeable*/ firOpBuilder. getUnitAttr (),
802
+ /* mergeable*/ mlir::UnitAttr (),
789
803
/* in_reduction_vars*/ mlir::ValueRange (), /* in_reductions*/ nullptr ,
790
804
/* priority*/ mlir::Value (),
791
805
mlir::ArrayAttr::get (converter.getFirOpBuilder ().getContext (),
792
806
clauseOps.dependTypeAttrs ),
793
807
clauseOps.dependVars , /* allocate_vars*/ mlir::ValueRange (),
794
808
/* allocate_vars*/ mlir::ValueRange ());
795
809
810
+ // Clear the dependencies so that the subsequent omp.target op doesn't have
811
+ // dependencies
812
+ clauseOps.dependTypeAttrs .clear ();
813
+ clauseOps.dependVars .clear ();
814
+
796
815
firOpBuilder.createBlock (&taskOp.getRegion ());
797
816
firOpBuilder.create <mlir::omp::TerminatorOp>(currentLocation);
798
817
firOpBuilder.setInsertionPointToStart (&taskOp.getRegion ().front ());
0 commit comments